* On persist and flush operations we must update any derived id fields.
*/
protected Object updateDerivedIds(Object clone, ClassDescriptor descriptor) {
if (descriptor.hasDerivedId()) {
for (DatabaseMapping derivesIdMapping : descriptor.getDerivesIdMappinps()) {
DatabaseMapping derivedIdMapping = derivesIdMapping.getDerivedIdMapping();
// If there is no derived id mapping, then there is no update required. Case #1a-#6a
// from the JPA spec.
if (derivedIdMapping != null) {
ClassDescriptor parentDescriptor = derivesIdMapping.getReferenceDescriptor();
Object parentClone = derivesIdMapping.getRealAttributeValueFromObject(clone, this);
// If the parent clone is null, we don't have any work to do, continue to the next
// mapping. Some mappings may be part of a composite primary key that allows for a
// null setting or the mapping may just not be set.
if (parentClone != null) {
Object key;
// Recurse up the chain to figure out the key. The first dependent will figure
// it out and pass it to its sub-dependents (keeping it the same)
if (parentDescriptor.hasDerivedId()) {
key = updateDerivedIds(parentClone, parentDescriptor);
} else {
key = parentDescriptor.getCMPPolicy().createPrimaryKeyInstance(parentClone, this);
}
if (derivesIdMapping.hasMapsIdValue()) {
// Case #1b, #2b and #3b from the JPA spec. The derived id is within our
// embedded id. We need to deal with that object and its mapping within the clone.
Object aggregateClone = derivedIdMapping.getRealAttributeValueFromObject(clone, this);
// If the aggregate clone is null, create one and set it on the clone.
if (aggregateClone == null) {
aggregateClone = derivedIdMapping.getReferenceDescriptor().getObjectBuilder().buildNewInstance();
derivedIdMapping.setRealAttributeValueInObject(clone, aggregateClone);
}
// Now get the actual derived id mapping from the aggregate and populate it on the aggregate clone.
DatabaseMapping aggregateMapping = derivedIdMapping.getReferenceDescriptor().getObjectBuilder().getMappingForAttributeName(derivesIdMapping.getMapsIdValue());
aggregateMapping.setRealAttributeValueInObject(aggregateClone, key);
} else {
// Case #4b, #5b, #6b from the JPA spec. Our id mapping is the derived id.
// We will deal with the clone provided.
derivedIdMapping.setRealAttributeValueInObject(clone, key);
}