[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Newsgroup Home]
[news.eclipse.rt.eclipselink] Order of mapping resolution

I am observing some interesting side-effects when using back-references where part of the foreign key is qualified by a grand-parent in the relationship. This is fairly in-depth, but I will do my best to explain it succinctly.

I have a three-tier one-to-many hierarchy, described by the following tables. Each table is keyed on a unique sequence-generated ID, and a string code which splits the schema vertically.

GRANDPARENT (GRANDPARENT_ID, CODE)
PARENT (PARENT_ID, CODE)
CHIILD (CHILD_ID, CODE)

My object model for this domain gives each object its own identifier, but stores the code on the grandparent only.

GrandParent
+ int identifier
+ String code
+ Collection<Parent> children

Parent
+ int identifier
+ GrandParent backRef
+ Collection<Child> children

Child
+ int identifier
+ Parent backRef

I map this through EclipseLink (We use the POJO ORM API as we came from TopLink) using direct-to-field mappings for the identifier fields; batch read one-to-many mappings for the forward going relationships; and one-to-one mappings for the back-references.

This appears to work fine, but I noticed that in some scenarios fetches were retrieving Parent objects whose Child objects were missing.

Debugging through the EclipseLink code, I noticed that for some one-to-many relationships, EclipseLink is trying to pull child records (from the pool of previously batch-read child candidates) using a correct parent sequence number key, but a code of null. Looking further into this, I discovered that EclipseLink is deriving the code by walking up the back-reference to the GrandParent, but that this back-reference hadn't been populated yet and was null. It appears that, for the mapping to work correctly, the backRef property of each domain object must be the first one to be populated, before the children property is addressed.

Looking in more detail at the way in which EclipseLink populates its relational mappings reveals the reason for the erratic behaviour we were observing. The order in which EclipseLink processes relational mappings is deemed to be unimportant, and is casually achieved by iterating over the result of a call to descriptor.getMappings() in the buildAttributesIntoObject method in org.eclipse.persistence.internal.descriptors.ObjectBuilder. This simply returns the key-set of the Map of relationships (keyed by their descriptors), and hence the order is arbitrarily determined by the hash values of the descriptors and the hashing function of the JVM. Small changes to our mappings were causing these hash values to change, and subsequently the order of relational mapping population to change.

Arguably, this is both a bug in EclipseLink and an oversight in our domain. Clearly, nobody in EclipseLink has ever considered the order of population of relational descriptors to be important. There are no efforts in the code to intelligently calculate the order, and there is no evidence of any exposure of that order to the user through the EclipseLink IDE. We should therefore consider that, although entirely achievable, it is incorrect to build a domain in such a way that the order of relational mapping evaluation becomes important.

The resolution for us, therefore, has been to re-architect our domain objects so that the code is propagated throughout, and to adjust the EclipseLink mappings to make use of these de-normalised codes so as to prevent the need for back-references to be populated first. However, to me this represents a pollution of our domain, and for this reason I am posting here to see if anybody else has experienced similar problems, or if anyone connected with EclipseLink would like to make a comment.

Regards,
Tom