use of org.eclipse.persistence.internal.descriptors.changetracking.AggregateAttributeChangeListener in project eclipselink by eclipse-ee4j.
the class SimpleTypes_AggregateObject method verifyChangTracking.
@Test
public void verifyChangTracking() {
persistSimpleA();
DynamicType simpleTypeA = dynamicHelper.getType("SimpleA");
Assert.assertNotNull(simpleTypeA);
UnitOfWork uow = session.acquireUnitOfWork();
ReadObjectQuery roq = dynamicHelper.newReadObjectQuery("SimpleA");
roq.setSelectionCriteria(roq.getExpressionBuilder().get("id").equal(1));
DynamicEntityImpl sharedA = (DynamicEntityImpl) session.executeQuery(roq);
assertNotNull(sharedA);
assertNull(sharedA._persistence_getPropertyChangeListener());
DynamicEntityImpl a = (DynamicEntityImpl) uow.executeQuery(roq);
assertNotNull(a);
assertNotNull(a._persistence_getPropertyChangeListener());
DynamicEntityImpl c = a.<DynamicEntityImpl>get("c");
assertNotNull(c);
assertNotNull(c._persistence_getPropertyChangeListener());
assertTrue(c._persistence_getPropertyChangeListener() instanceof AggregateAttributeChangeListener);
uow.release();
}
use of org.eclipse.persistence.internal.descriptors.changetracking.AggregateAttributeChangeListener in project eclipselink by eclipse-ee4j.
the class AggregateMapping method updateChangeRecord.
/**
* INTERNAL:
* Either create a new change record or update the change record with the new value.
* This is used by attribute change tracking.
*/
@Override
public void updateChangeRecord(Object sourceClone, Object newValue, Object oldValue, ObjectChangeSet objectChangeSet, UnitOfWorkImpl uow) throws DescriptorException {
// This method will be called when either the referenced aggregate has
// been changed or a component of the referenced aggregate has been changed
// this case is determined by the value of the sourceClone
boolean isNewRecord = false;
AggregateChangeRecord changeRecord = (AggregateChangeRecord) objectChangeSet.getChangesForAttributeNamed(this.getAttributeName());
if (changeRecord == null) {
changeRecord = new AggregateChangeRecord(objectChangeSet);
changeRecord.setAttribute(this.getAttributeName());
changeRecord.setMapping(this);
objectChangeSet.addChange(changeRecord);
isNewRecord = true;
}
if (sourceClone.getClass().equals(objectChangeSet.getClassType(uow))) {
if (isNewRecord) {
changeRecord.setOldValue(oldValue);
}
// event was fired on the parent to the aggregate, the attribute value changed.
ClassDescriptor referenceDescriptor = getReferenceDescriptor(newValue, uow);
if (newValue == null) {
// attribute set to null
changeRecord.setChangedObject(null);
if (referenceDescriptor.getObjectChangePolicy().isAttributeChangeTrackingPolicy()) {
if (((ChangeTracker) oldValue)._persistence_getPropertyChangeListener() != null) {
// need to detach listener
((AggregateAttributeChangeListener) ((ChangeTracker) oldValue)._persistence_getPropertyChangeListener()).setParentListener(null);
}
}
return;
} else {
// attribute set to new aggregate
UnitOfWorkChangeSet uowChangeSet = (UnitOfWorkChangeSet) objectChangeSet.getUOWChangeSet();
// force comparison change detection to build changeset.
ObjectChangeSet aggregateChangeSet = (ObjectChangeSet) uowChangeSet.getObjectChangeSetForClone(newValue);
if (aggregateChangeSet != null && aggregateChangeSet.getDescriptor() == referenceDescriptor) {
// old differences must be thrown away because difference is between old value and new value
aggregateChangeSet.clear(true);
}
// make sure the listener is initialized
if (referenceDescriptor.getObjectChangePolicy().isAttributeChangeTrackingPolicy()) {
if (oldValue != null && ((ChangeTracker) oldValue)._persistence_getPropertyChangeListener() != null) {
// need to detach listener
((AggregateAttributeChangeListener) ((ChangeTracker) oldValue)._persistence_getPropertyChangeListener()).setParentListener(null);
}
// need to attach new listener.
AggregateAttributeChangeListener newListener = (AggregateAttributeChangeListener) ((ChangeTracker) newValue)._persistence_getPropertyChangeListener();
if (newListener == null) {
newListener = new AggregateAttributeChangeListener(referenceDescriptor, uow, ((AttributeChangeListener) ((ChangeTracker) sourceClone)._persistence_getPropertyChangeListener()), this.getAttributeName(), newValue);
((ChangeTracker) newValue)._persistence_setPropertyChangeListener(newListener);
}
newListener.setParentListener((AttributeChangeListener) ((ChangeTracker) sourceClone)._persistence_getPropertyChangeListener());
if (changeRecord.getChangedObject() != null && changeRecord.getChangedObject().hasChanges()) {
// the oldValue has been already changed - get the original oldValue.
oldValue = changeRecord.getOldValue();
}
if (oldValue != null) {
if (referenceDescriptor != getReferenceDescriptor(oldValue, uow)) {
// oldValue and newValue belong to different types - have to start from scratch.
oldValue = null;
}
}
}
// force comparison change detection to build changeset.
changeRecord.setChangedObject(referenceDescriptor.getObjectChangePolicy().createObjectChangeSetThroughComparison(newValue, oldValue, uowChangeSet, (oldValue == null), uow, referenceDescriptor));
// process nested aggregates
for (DatabaseMapping mapping : referenceDescriptor.getMappings()) {
if (mapping.isAggregateObjectMapping()) {
Object nestedNewValue = mapping.getAttributeValueFromObject(newValue);
Object nestedOldValue = null;
if (oldValue != null) {
nestedOldValue = mapping.getAttributeValueFromObject(oldValue);
}
// bug #413120 - update nested change record only if the value is different
if (nestedNewValue != nestedOldValue) {
mapping.updateChangeRecord(newValue, nestedNewValue, nestedOldValue, (org.eclipse.persistence.internal.sessions.ObjectChangeSet) changeRecord.getChangedObject(), uow);
}
}
}
referenceDescriptor.getObjectChangePolicy().setChangeSetOnListener((ObjectChangeSet) changeRecord.getChangedObject(), newValue);
}
} else {
// a value was set on the aggregate but the aggregate was not changed.
if (referenceDescriptor.getObjectChangePolicy().isAttributeChangeTrackingPolicy()) {
// The aggregate that is referenced is Attribute Change Tracked as well.
changeRecord.setChangedObject(((AggregateAttributeChangeListener) ((ChangeTracker) sourceClone)._persistence_getPropertyChangeListener()).getObjectChangeSet());
} else {
// not tracked at attribute level, lets force build a changeset then.
changeRecord.setChangedObject(referenceDescriptor.getObjectChangePolicy().createObjectChangeSetThroughComparison(sourceClone, null, (UnitOfWorkChangeSet) objectChangeSet.getUOWChangeSet(), true, uow, referenceDescriptor));
}
}
}
use of org.eclipse.persistence.internal.descriptors.changetracking.AggregateAttributeChangeListener in project eclipselink by eclipse-ee4j.
the class SimpleTypes_AggregateObject method verifyChangTracking.
@Test
public void verifyChangTracking() {
persistSimpleA();
DynamicTypeImpl simpleTypeA = (DynamicTypeImpl) helper.getType("SimpleA");
assertNotNull(simpleTypeA);
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
DynamicEntityImpl a = (DynamicEntityImpl) em.find(simpleTypeA.getJavaClass(), 1);
assertNotNull(a);
assertNotNull(a._persistence_getPropertyChangeListener());
DynamicEntityImpl c = a.<DynamicEntityImpl>get("c");
assertNotNull(c);
assertNotNull(c._persistence_getPropertyChangeListener());
assertTrue(c._persistence_getPropertyChangeListener() instanceof AggregateAttributeChangeListener);
em.getTransaction().rollback();
em.close();
}
Aggregations