Skip to content

EntityStates.isLoaded returns true for any attribute of an entity returned by DataManager.getReference #5660

Description

@knstvk

Description

DataManager.getReference() returns an entity instance that carries nothing but the id. However, EntityStates.isLoaded() reports every attribute of such an instance as loaded, and EntityStates.isLoadedWithFetchPlan() reports that it conforms to any fetch plan.

As a result, code that uses these methods to find out whether an instance actually has data cannot tell a reference from a fully loaded entity, and treats the nulls as real values.

Steps to reproduce

Order order = dataManager.getReference(Order.class, someId);

entityStates.isLoaded(order, "number");      // local attribute
entityStates.isLoaded(order, "customer");    // to-one reference
entityStates.isLoaded(order, "orderLines");  // to-many collection
entityStates.isLoadedWithFetchPlan(order, FetchPlan.BASE);

Actual behavior

All the calls return true.

EntityStates.isLoadedSafe() returns UNKNOWN for every attribute, so it does not help either, and EntityStates.getCurrentFetchPlan() returns a fetch plan containing all attributes of the entity.

Expected behavior

An attribute that was never fetched is reported as not loaded, so a reference instance reports only its id as loaded:

  • isLoaded() returns false for all attributes except the id.
  • isLoadedSafe() returns NO for them, without invoking getters.
  • isLoadedWithFetchPlan() returns false for a fetch plan that contains anything besides the id.
  • getCurrentFetchPlan() returns a fetch plan with the id only.

Impact

  • EntitySerialization decides which attributes to write from isLoaded(), so a reference is serialized as a complete entity full of nulls. This affects REST, BPM process variables, and everything else built on entity serialization.
  • DataContext.merge() copies attributes from the source when isLoaded() is true for them, so merging a reference into a context that already holds the loaded instance overwrites real values with nulls.
  • Application code that reloads an entity only when the required attributes are missing skips the reload and keeps working with nulls.

Note that saving a reference is not affected: it is a patch instance, so only non-null attributes are written to the database.

Reproduced on 3.1.999-SNAPSHOT with the EclipseLink data store.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions