[hibernate-commits] Hibernate SVN: r16393 - in core/trunk/envers/src: main/java/org/hibernate/envers/entities/mapper/relation and 6 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Wed Apr 22 04:38:05 EDT 2009


Author: adamw
Date: 2009-04-22 04:38:05 -0400 (Wed, 22 Apr 2009)
New Revision: 16393

Added:
   core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reference/
   core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reference/BidirectionalReference.java
   core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reference/GreetingPO.java
   core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reference/GreetingSetPO.java
Modified:
   core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/ComponentPropertyMapper.java
   core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/ExtendedPropertyMapper.java
   core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/MultiPropertyMapper.java
   core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/PropertyMapper.java
   core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/SinglePropertyMapper.java
   core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/SubclassPropertyMapper.java
   core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/relation/AbstractCollectionMapper.java
   core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/relation/OneToOneNotOwningMapper.java
   core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/relation/ToOneIdMapper.java
   core/trunk/envers/src/main/java/org/hibernate/envers/event/AuditEventListener.java
   core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/AbstractAuditWorkUnit.java
   core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/AddWorkUnit.java
   core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/CollectionChangeWorkUnit.java
   core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/DelWorkUnit.java
   core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/ModWorkUnit.java
   core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/PersistentCollectionChangeWorkUnit.java
   core/trunk/envers/src/main/java/org/hibernate/envers/tools/Tools.java
   core/trunk/envers/src/test/resources/testng.xml
Log:
HHH-3871:
- not loading proxied objects when not necessary
- test

Modified: core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/ComponentPropertyMapper.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/ComponentPropertyMapper.java	2009-04-22 06:52:05 UTC (rev 16392)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/ComponentPropertyMapper.java	2009-04-22 08:38:05 UTC (rev 16393)
@@ -36,6 +36,7 @@
 import org.hibernate.collection.PersistentCollection;
 import org.hibernate.property.Setter;
 import org.hibernate.util.ReflectHelper;
+import org.hibernate.engine.SessionImplementor;
 
 /**
  * @author Adam Warski (adam at warski dot org)
@@ -63,8 +64,8 @@
         delegate.addComposite(propertyData, propertyMapper);
     }
 
-    public boolean mapToMapFromEntity(Map<String, Object> data, Object newObj, Object oldObj) {
-        return delegate.mapToMapFromEntity(data, newObj, oldObj);
+    public boolean mapToMapFromEntity(SessionImplementor session, Map<String, Object> data, Object newObj, Object oldObj) {
+        return delegate.mapToMapFromEntity(session, data, newObj, oldObj);
     }
 
     public void mapToEntityFromMap(AuditConfiguration verCfg, Object obj, Map data, Object primaryKey, AuditReaderImplementor versionsReader, Number revision) {

Modified: core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/ExtendedPropertyMapper.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/ExtendedPropertyMapper.java	2009-04-22 06:52:05 UTC (rev 16392)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/ExtendedPropertyMapper.java	2009-04-22 08:38:05 UTC (rev 16393)
@@ -23,11 +23,13 @@
  */
 package org.hibernate.envers.entities.mapper;
 
+import org.hibernate.engine.SessionImplementor;
+
 import java.util.Map;
 
 /**
  * @author Adam Warski (adam at warski dot org)
  */
 public interface ExtendedPropertyMapper extends PropertyMapper, CompositeMapperBuilder {
-    public boolean map(Map<String, Object> data, String[] propertyNames, Object[] newState, Object[] oldState);
+    public boolean map(SessionImplementor session, Map<String, Object> data, String[] propertyNames, Object[] newState, Object[] oldState);
 }

Modified: core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/MultiPropertyMapper.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/MultiPropertyMapper.java	2009-04-22 06:52:05 UTC (rev 16392)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/MultiPropertyMapper.java	2009-04-22 08:38:05 UTC (rev 16393)
@@ -36,6 +36,7 @@
 
 import org.hibernate.collection.PersistentCollection;
 import org.hibernate.property.Getter;
+import org.hibernate.engine.SessionImplementor;
 
 /**
  * @author Adam Warski (adam at warski dot org)
@@ -75,13 +76,13 @@
 
     private Object getAtIndexOrNull(Object[] array, int index) { return array == null ? null : array[index]; }
 
-    public boolean map(Map<String, Object> data, String[] propertyNames, Object[] newState, Object[] oldState) {
+    public boolean map(SessionImplementor session, Map<String, Object> data, String[] propertyNames, Object[] newState, Object[] oldState) {
         boolean ret = false;
         for (int i=0; i<propertyNames.length; i++) {
             String propertyName = propertyNames[i];
 
             if (propertyDatas.containsKey(propertyName)) {
-                ret |= properties.get(propertyDatas.get(propertyName)).mapToMapFromEntity(data,
+                ret |= properties.get(propertyDatas.get(propertyName)).mapToMapFromEntity(session, data,
                         getAtIndexOrNull(newState, i),
                         getAtIndexOrNull(oldState, i));
             }
@@ -90,7 +91,7 @@
         return ret;
     }
 
-    public boolean mapToMapFromEntity(Map<String, Object> data, Object newObj, Object oldObj) {
+    public boolean mapToMapFromEntity(SessionImplementor session, Map<String, Object> data, Object newObj, Object oldObj) {
         boolean ret = false;
         for (PropertyData propertyData : properties.keySet()) {
             Getter getter;
@@ -102,7 +103,7 @@
                 return false;
             }
 
-            ret |= properties.get(propertyData).mapToMapFromEntity(data,
+            ret |= properties.get(propertyData).mapToMapFromEntity(session, data,
                     newObj == null ? null : getter.get(newObj),
                     oldObj == null ? null : getter.get(oldObj));
         }

Modified: core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/PropertyMapper.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/PropertyMapper.java	2009-04-22 06:52:05 UTC (rev 16392)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/PropertyMapper.java	2009-04-22 08:38:05 UTC (rev 16393)
@@ -31,6 +31,7 @@
 import org.hibernate.envers.reader.AuditReaderImplementor;
 
 import org.hibernate.collection.PersistentCollection;
+import org.hibernate.engine.SessionImplementor;
 
 /**
  * @author Adam Warski (adam at warski dot org)
@@ -38,12 +39,13 @@
 public interface PropertyMapper {
     /**
      * Maps properties to the given map, basing on differences between properties of new and old objects.
-     * @param data Data to map to.
-     * @param newObj New state of the entity.
-     * @param oldObj Old state of the entity.
-     * @return True if there are any differences between the states represented by newObj and oldObj.
+     * @param session The current session.
+	 * @param data Data to map to.
+	 * @param newObj New state of the entity.
+	 * @param oldObj Old state of the entity.
+	 * @return True if there are any differences between the states represented by newObj and oldObj.
      */
-    boolean mapToMapFromEntity(Map<String, Object> data, Object newObj, Object oldObj);
+    boolean mapToMapFromEntity(SessionImplementor session, Map<String, Object> data, Object newObj, Object oldObj);
 
     /**
      * Maps properties from the given map to the given object.

Modified: core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/SinglePropertyMapper.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/SinglePropertyMapper.java	2009-04-22 06:52:05 UTC (rev 16392)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/SinglePropertyMapper.java	2009-04-22 08:38:05 UTC (rev 16393)
@@ -36,6 +36,7 @@
 
 import org.hibernate.collection.PersistentCollection;
 import org.hibernate.property.Setter;
+import org.hibernate.engine.SessionImplementor;
 
 /**
  * TODO: diff
@@ -54,7 +55,7 @@
         this.propertyData = propertyData;
     }
 
-    public boolean mapToMapFromEntity(Map<String, Object> data, Object newObj, Object oldObj) {
+    public boolean mapToMapFromEntity(SessionImplementor session, Map<String, Object> data, Object newObj, Object oldObj) {
         data.put(propertyData.getName(), newObj);
 
         return !Tools.objectsEqual(newObj, oldObj);

Modified: core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/SubclassPropertyMapper.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/SubclassPropertyMapper.java	2009-04-22 06:52:05 UTC (rev 16392)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/SubclassPropertyMapper.java	2009-04-22 08:38:05 UTC (rev 16393)
@@ -32,6 +32,7 @@
 import org.hibernate.envers.reader.AuditReaderImplementor;
 
 import org.hibernate.collection.PersistentCollection;
+import org.hibernate.engine.SessionImplementor;
 
 /**
  * A mapper which maps from a parent mapper and a "main" one, but adds only to the "main". The "main" mapper
@@ -47,16 +48,16 @@
         this.parentMapper = parentMapper;
     }
 
-    public boolean map(Map<String, Object> data, String[] propertyNames, Object[] newState, Object[] oldState) {
-        boolean parentDiffs = parentMapper.map(data, propertyNames, newState, oldState);
-        boolean mainDiffs = main.map(data, propertyNames, newState, oldState);
+    public boolean map(SessionImplementor session, Map<String, Object> data, String[] propertyNames, Object[] newState, Object[] oldState) {
+        boolean parentDiffs = parentMapper.map(session, data, propertyNames, newState, oldState);
+        boolean mainDiffs = main.map(session, data, propertyNames, newState, oldState);
 
         return parentDiffs || mainDiffs;
     }
 
-    public boolean mapToMapFromEntity(Map<String, Object> data, Object newObj, Object oldObj) {
-        boolean parentDiffs = parentMapper.mapToMapFromEntity(data, newObj, oldObj);
-        boolean mainDiffs = main.mapToMapFromEntity(data, newObj, oldObj);
+    public boolean mapToMapFromEntity(SessionImplementor session, Map<String, Object> data, Object newObj, Object oldObj) {
+        boolean parentDiffs = parentMapper.mapToMapFromEntity(session, data, newObj, oldObj);
+        boolean mainDiffs = main.mapToMapFromEntity(session, data, newObj, oldObj);
 
         return parentDiffs || mainDiffs;
     }

Modified: core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/relation/AbstractCollectionMapper.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/relation/AbstractCollectionMapper.java	2009-04-22 06:52:05 UTC (rev 16392)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/relation/AbstractCollectionMapper.java	2009-04-22 08:38:05 UTC (rev 16393)
@@ -45,6 +45,7 @@
 
 import org.hibernate.collection.PersistentCollection;
 import org.hibernate.property.Setter;
+import org.hibernate.engine.SessionImplementor;
 
 /**
  * @author Adam Warski (adam at warski dot org)
@@ -130,7 +131,7 @@
         return collectionChanges;
     }
 
-    public boolean mapToMapFromEntity(Map<String, Object> data, Object newObj, Object oldObj) {
+    public boolean mapToMapFromEntity(SessionImplementor session, Map<String, Object> data, Object newObj, Object oldObj) {
         // Changes are mapped in the "mapCollectionChanges" method.
         return false;
     }

Modified: core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/relation/OneToOneNotOwningMapper.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/relation/OneToOneNotOwningMapper.java	2009-04-22 06:52:05 UTC (rev 16392)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/relation/OneToOneNotOwningMapper.java	2009-04-22 08:38:05 UTC (rev 16393)
@@ -38,6 +38,7 @@
 import org.hibernate.envers.tools.reflection.ReflectionTools;
 
 import org.hibernate.NonUniqueResultException;
+import org.hibernate.engine.SessionImplementor;
 import org.hibernate.collection.PersistentCollection;
 import org.hibernate.property.Setter;
 
@@ -56,7 +57,7 @@
         this.propertyData = propertyData;
     }
 
-    public boolean mapToMapFromEntity(Map<String, Object> data, Object newObj, Object oldObj) {
+    public boolean mapToMapFromEntity(SessionImplementor session, Map<String, Object> data, Object newObj, Object oldObj) {
         return false;
     }
 

Modified: core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/relation/ToOneIdMapper.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/relation/ToOneIdMapper.java	2009-04-22 06:52:05 UTC (rev 16392)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/entities/mapper/relation/ToOneIdMapper.java	2009-04-22 08:38:05 UTC (rev 16393)
@@ -40,6 +40,7 @@
 
 import org.hibernate.collection.PersistentCollection;
 import org.hibernate.property.Setter;
+import org.hibernate.engine.SessionImplementor;
 
 /**
  * @author Adam Warski (adam at warski dot org)
@@ -55,13 +56,13 @@
         this.referencedEntityName = referencedEntityName;
     }
 
-    public boolean mapToMapFromEntity(Map<String, Object> data, Object newObj, Object oldObj) {
+    public boolean mapToMapFromEntity(SessionImplementor session, Map<String, Object> data, Object newObj, Object oldObj) {
         HashMap<String, Object> newData = new HashMap<String, Object>();
         data.put(propertyData.getName(), newData);
 
         delegate.mapToMapFromEntity(newData, newObj);
 
-        return !Tools.objectsEqual(newObj, oldObj);
+        return !Tools.entitiesEqual(session, newObj, oldObj);
     }
 
     public void mapToEntityFromMap(AuditConfiguration verCfg, Object obj, Map data, Object primaryKey,

Modified: core/trunk/envers/src/main/java/org/hibernate/envers/event/AuditEventListener.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/event/AuditEventListener.java	2009-04-22 06:52:05 UTC (rev 16392)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/event/AuditEventListener.java	2009-04-22 08:38:05 UTC (rev 16393)
@@ -90,41 +90,49 @@
                 Object oldValue = oldState == null ? null : oldState[i];
                 Object newValue = newState == null ? null : newState[i];
 
-                if (!Tools.objectsEqual(oldValue, newValue)) {
+                if (!Tools.entitiesEqual(session, oldValue, newValue)) {
                     // We have to generate changes both in the old collection (size decreses) and new collection
                     // (size increases).
                     if (newValue != null) {
                         // relDesc.getToEntityName() doesn't always return the entity name of the value - in case
                         // of subclasses, this will be root class, no the actual class. So it can't be used here.
                         String toEntityName;
-                        if(newValue instanceof HibernateProxy) {
+						Serializable id;
+
+                        if (newValue instanceof HibernateProxy) {
                     	    HibernateProxy hibernateProxy = (HibernateProxy) newValue;
                     	    toEntityName = session.bestGuessEntityName(newValue);
-                    	    newValue = hibernateProxy.getHibernateLazyInitializer().getImplementation();
+                    	    id = hibernateProxy.getHibernateLazyInitializer().getIdentifier();
+							// We've got to initialize the object from the proxy to later read its state.   
+							newValue = Tools.getTargetFromProxy(hibernateProxy);
                     	} else {
                     		toEntityName =  session.guessEntityName(newValue);
+
+							IdMapper idMapper = verCfg.getEntCfg().get(toEntityName).getIdMapper();
+                         	id = (Serializable) idMapper.mapToIdFromEntity(newValue);
                     	}
 
-                        IdMapper idMapper = verCfg.getEntCfg().get(toEntityName).getIdMapper();
-
-                        Serializable id = (Serializable) idMapper.mapToIdFromEntity(newValue);
-                        verSync.addWorkUnit(new CollectionChangeWorkUnit(toEntityName, verCfg, id, newValue));
+                        verSync.addWorkUnit(new CollectionChangeWorkUnit(session, toEntityName, verCfg, id, newValue));
                     }
 
                     if (oldValue != null) {
                     	String toEntityName;
+						Serializable id;
+
                     	if(oldValue instanceof HibernateProxy) {
                     	    HibernateProxy hibernateProxy = (HibernateProxy) oldValue;
                     	    toEntityName = session.bestGuessEntityName(oldValue);
-                    	    oldValue = hibernateProxy.getHibernateLazyInitializer().getImplementation();
+                    	    id = hibernateProxy.getHibernateLazyInitializer().getIdentifier();
+							// We've got to initialize the object as we'll read it's state anyway.
+							oldValue = Tools.getTargetFromProxy(hibernateProxy);
                     	} else {
                     		toEntityName =  session.guessEntityName(oldValue);
+
+							IdMapper idMapper = verCfg.getEntCfg().get(toEntityName).getIdMapper();
+							id = (Serializable) idMapper.mapToIdFromEntity(oldValue);
                     	}
-                        
-                        IdMapper idMapper = verCfg.getEntCfg().get(toEntityName).getIdMapper();
-
-                        Serializable id = (Serializable) idMapper.mapToIdFromEntity(oldValue);
-                        verSync.addWorkUnit(new CollectionChangeWorkUnit(toEntityName, verCfg, id, oldValue));
+						
+                        verSync.addWorkUnit(new CollectionChangeWorkUnit(session, toEntityName, verCfg, id, oldValue));
                     }
                 }
             }
@@ -137,8 +145,8 @@
         if (verCfg.getEntCfg().isVersioned(entityName)) {
             AuditSync verSync = verCfg.getSyncManager().get(event.getSession());
 
-            verSync.addWorkUnit(new AddWorkUnit(event.getPersister().getEntityName(), verCfg, event.getId(),
-                    event.getPersister(), event.getState()));
+            verSync.addWorkUnit(new AddWorkUnit(event.getSession(), event.getPersister().getEntityName(), verCfg,
+					event.getId(), event.getPersister(), event.getState()));
 
             generateBidirectionalCollectionChangeWorkUnits(verSync, event.getPersister(), entityName, event.getState(),
                     null, event.getSession());
@@ -151,8 +159,8 @@
         if (verCfg.getEntCfg().isVersioned(entityName)) {
             AuditSync verSync = verCfg.getSyncManager().get(event.getSession());
 
-            verSync.addWorkUnit(new ModWorkUnit(event.getPersister().getEntityName(), verCfg, event.getId(),
-                    event.getPersister(), event.getState(), event.getOldState()));
+            verSync.addWorkUnit(new ModWorkUnit(event.getSession(), event.getPersister().getEntityName(), verCfg,
+					event.getId(), event.getPersister(), event.getState(), event.getOldState()));
 
             generateBidirectionalCollectionChangeWorkUnits(verSync, event.getPersister(), entityName, event.getState(),
                     event.getOldState(), event.getSession());
@@ -165,7 +173,8 @@
         if (verCfg.getEntCfg().isVersioned(entityName)) {
             AuditSync verSync = verCfg.getSyncManager().get(event.getSession());
 
-            verSync.addWorkUnit(new DelWorkUnit(event.getPersister().getEntityName(), verCfg, event.getId()));
+            verSync.addWorkUnit(new DelWorkUnit(event.getSession(), event.getPersister().getEntityName(), verCfg,
+					event.getId()));
 
             generateBidirectionalCollectionChangeWorkUnits(verSync, event.getPersister(), entityName, null,
                     event.getDeletedState(), event.getSession());
@@ -193,7 +202,8 @@
                 Object relatedObj = changeData.getChangedElement();
                 Serializable relatedId = (Serializable) relatedIdMapper.mapToIdFromEntity(relatedObj);
 
-                verSync.addWorkUnit(new CollectionChangeWorkUnit(relatedEntityName, verCfg, relatedId, relatedObj));
+                verSync.addWorkUnit(new CollectionChangeWorkUnit(event.getSession(), relatedEntityName, verCfg,
+						relatedId, relatedObj));
             }
         }
     }
@@ -205,14 +215,14 @@
         if (verCfg.getEntCfg().isVersioned(entityName)) {
             AuditSync verSync = verCfg.getSyncManager().get(event.getSession());
 
-            PersistentCollectionChangeWorkUnit workUnit = new PersistentCollectionChangeWorkUnit(entityName, verCfg,
-                    newColl, collectionEntry, oldColl, event.getAffectedOwnerIdOrNull());
+            PersistentCollectionChangeWorkUnit workUnit = new PersistentCollectionChangeWorkUnit(event.getSession(),
+					entityName, verCfg, newColl, collectionEntry, oldColl, event.getAffectedOwnerIdOrNull());
             verSync.addWorkUnit(workUnit);
 
             if (workUnit.containsWork()) {
                 // There are some changes: a revision needs also be generated for the collection owner
-                verSync.addWorkUnit(new CollectionChangeWorkUnit(event.getAffectedOwnerEntityName(), verCfg,
-                        event.getAffectedOwnerIdOrNull(), event.getAffectedOwnerOrNull()));
+                verSync.addWorkUnit(new CollectionChangeWorkUnit(event.getSession(), event.getAffectedOwnerEntityName(),
+						verCfg, event.getAffectedOwnerIdOrNull(), event.getAffectedOwnerOrNull()));
 
                 generateBidirectionalCollectionChangeWorkUnits(verSync, event, workUnit);
             }

Modified: core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/AbstractAuditWorkUnit.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/AbstractAuditWorkUnit.java	2009-04-22 06:52:05 UTC (rev 16392)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/AbstractAuditWorkUnit.java	2009-04-22 08:38:05 UTC (rev 16393)
@@ -32,11 +32,13 @@
 import org.hibernate.envers.configuration.AuditEntitiesConfiguration;
 
 import org.hibernate.Session;
+import org.hibernate.engine.SessionImplementor;
 
 /**
  * @author Adam Warski (adam at warski dot org)
  */
 public abstract class AbstractAuditWorkUnit implements AuditWorkUnit {
+	protected final SessionImplementor sessionImplementor;
     protected final AuditConfiguration verCfg;
     protected final Serializable id;
 
@@ -44,7 +46,9 @@
 
     private Object performedData;
 
-    protected AbstractAuditWorkUnit(String entityName, AuditConfiguration verCfg, Serializable id) {
+    protected AbstractAuditWorkUnit(SessionImplementor sessionImplementor, String entityName, AuditConfiguration verCfg,
+									Serializable id) {
+		this.sessionImplementor = sessionImplementor;
         this.verCfg = verCfg;
         this.id = id;
         this.entityName = entityName;

Modified: core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/AddWorkUnit.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/AddWorkUnit.java	2009-04-22 06:52:05 UTC (rev 16392)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/AddWorkUnit.java	2009-04-22 08:38:05 UTC (rev 16393)
@@ -31,6 +31,7 @@
 import org.hibernate.envers.configuration.AuditConfiguration;
 
 import org.hibernate.Session;
+import org.hibernate.engine.SessionImplementor;
 import org.hibernate.persister.entity.EntityPersister;
 
 /**
@@ -40,9 +41,9 @@
     private final Object[] state;
     private final String[] propertyNames;
 
-    public AddWorkUnit(String entityName, AuditConfiguration verCfg, Serializable id,
-                       EntityPersister entityPersister, Object[] state) {
-        super(entityName, verCfg, id);
+    public AddWorkUnit(SessionImplementor sessionImplementor, String entityName, AuditConfiguration verCfg,
+					   Serializable id, EntityPersister entityPersister, Object[] state) {
+        super(sessionImplementor, entityName, verCfg, id);
 
         this.state = state;
         this.propertyNames = entityPersister.getPropertyNames();
@@ -56,7 +57,8 @@
         Map<String, Object> data = new HashMap<String, Object>();
         fillDataWithId(data, revisionData, RevisionType.ADD);
 
-        verCfg.getEntCfg().get(getEntityName()).getPropertyMapper().map(data, propertyNames, state, null);
+        verCfg.getEntCfg().get(getEntityName()).getPropertyMapper().map(sessionImplementor, data,
+				propertyNames, state, null);
 
         session.save(verCfg.getAuditEntCfg().getAuditEntityName(getEntityName()), data);
 

Modified: core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/CollectionChangeWorkUnit.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/CollectionChangeWorkUnit.java	2009-04-22 06:52:05 UTC (rev 16392)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/CollectionChangeWorkUnit.java	2009-04-22 08:38:05 UTC (rev 16393)
@@ -31,6 +31,7 @@
 import org.hibernate.envers.configuration.AuditConfiguration;
 
 import org.hibernate.Session;
+import org.hibernate.engine.SessionImplementor;
 
 /**
  * @author Adam Warski (adam at warski dot org)
@@ -38,8 +39,9 @@
 public class CollectionChangeWorkUnit extends AbstractAuditWorkUnit implements AuditWorkUnit {
     private final Object entity;
 
-    public CollectionChangeWorkUnit(String entityName, AuditConfiguration verCfg, Serializable id, Object entity) {
-        super(entityName, verCfg, id);
+    public CollectionChangeWorkUnit(SessionImplementor session, String entityName, AuditConfiguration verCfg,
+									Serializable id, Object entity) {
+        super(session, entityName, verCfg, id);
 
         this.entity = entity;
     }
@@ -52,7 +54,8 @@
         Map<String, Object> data = new HashMap<String, Object>();
         fillDataWithId(data, revisionData, RevisionType.MOD);
 
-        verCfg.getEntCfg().get(getEntityName()).getPropertyMapper().mapToMapFromEntity(data, entity, null);
+        verCfg.getEntCfg().get(getEntityName()).getPropertyMapper().mapToMapFromEntity(sessionImplementor,
+				data, entity, null);
 
         session.save(verCfg.getAuditEntCfg().getAuditEntityName(getEntityName()), data);
 

Modified: core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/DelWorkUnit.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/DelWorkUnit.java	2009-04-22 06:52:05 UTC (rev 16392)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/DelWorkUnit.java	2009-04-22 08:38:05 UTC (rev 16393)
@@ -31,13 +31,14 @@
 import org.hibernate.envers.configuration.AuditConfiguration;
 
 import org.hibernate.Session;
+import org.hibernate.engine.SessionImplementor;
 
 /**
  * @author Adam Warski (adam at warski dot org)
  */
 public class DelWorkUnit extends AbstractAuditWorkUnit implements AuditWorkUnit {
-    public DelWorkUnit(String entityName, AuditConfiguration verCfg, Serializable id) {
-        super(entityName, verCfg, id);
+    public DelWorkUnit(SessionImplementor sessionImplementor, String entityName, AuditConfiguration verCfg, Serializable id) {
+        super(sessionImplementor, entityName, verCfg, id);
     }
 
     public boolean containsWork() {

Modified: core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/ModWorkUnit.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/ModWorkUnit.java	2009-04-22 06:52:05 UTC (rev 16392)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/ModWorkUnit.java	2009-04-22 08:38:05 UTC (rev 16393)
@@ -31,6 +31,7 @@
 import org.hibernate.envers.configuration.AuditConfiguration;
 
 import org.hibernate.Session;
+import org.hibernate.engine.SessionImplementor;
 import org.hibernate.persister.entity.EntityPersister;
 
 /**
@@ -40,13 +41,13 @@
     private final Map<String, Object> data;
     private final boolean changes;        
 
-    public ModWorkUnit(String entityName, AuditConfiguration verCfg, Serializable id,
-                       EntityPersister entityPersister, Object[] newState, Object[] oldState) {
-        super(entityName, verCfg, id);
+    public ModWorkUnit(SessionImplementor sessionImplementor, String entityName, AuditConfiguration verCfg, 
+					   Serializable id, EntityPersister entityPersister, Object[] newState, Object[] oldState) {
+        super(sessionImplementor, entityName, verCfg, id);
 
         data = new HashMap<String, Object>();
-        changes = verCfg.getEntCfg().get(getEntityName()).getPropertyMapper().map(data, entityPersister.getPropertyNames(),
-                newState, oldState);
+        changes = verCfg.getEntCfg().get(getEntityName()).getPropertyMapper().map(sessionImplementor, data,
+				entityPersister.getPropertyNames(), newState, oldState);
     }
 
     public boolean containsWork() {

Modified: core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/PersistentCollectionChangeWorkUnit.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/PersistentCollectionChangeWorkUnit.java	2009-04-22 06:52:05 UTC (rev 16392)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/PersistentCollectionChangeWorkUnit.java	2009-04-22 08:38:05 UTC (rev 16393)
@@ -34,6 +34,7 @@
 import org.hibernate.Session;
 import org.hibernate.persister.collection.AbstractCollectionPersister;
 import org.hibernate.engine.CollectionEntry;
+import org.hibernate.engine.SessionImplementor;
 import org.hibernate.collection.PersistentCollection;
 
 /**
@@ -43,10 +44,10 @@
     private final List<PersistentCollectionChangeData> collectionChanges;
     private final String referencingPropertyName;
 
-    public PersistentCollectionChangeWorkUnit(String entityName, AuditConfiguration verCfg,
-                                              PersistentCollection collection, CollectionEntry collectionEntry,
-                                              Serializable snapshot, Serializable id) {
-        super(entityName, verCfg, null);
+    public PersistentCollectionChangeWorkUnit(SessionImplementor sessionImplementor, String entityName,
+											  AuditConfiguration verCfg, PersistentCollection collection,
+											  CollectionEntry collectionEntry, Serializable snapshot, Serializable id) {
+        super(sessionImplementor, entityName, verCfg, null);
 
 		String ownerEntityName = ((AbstractCollectionPersister) collectionEntry.getLoadedPersister()).getOwnerEntityName();
 		referencingPropertyName = collectionEntry.getRole().substring(ownerEntityName.length() + 1);

Modified: core/trunk/envers/src/main/java/org/hibernate/envers/tools/Tools.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/tools/Tools.java	2009-04-22 06:52:05 UTC (rev 16392)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/tools/Tools.java	2009-04-22 08:38:05 UTC (rev 16393)
@@ -23,6 +23,10 @@
  */
 package org.hibernate.envers.tools;
 
+import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.Session;
+
 import java.util.*;
 
 /**
@@ -41,6 +45,42 @@
         return new LinkedHashMap<K,V>();
     }
 
+	public static boolean entitiesEqual(SessionImplementor session, Object obj1, Object obj2) {
+        Object id1 = getIdentifier(session, obj1);
+		Object id2 = getIdentifier(session, obj2);
+
+        return objectsEqual(id1, id2);
+    }
+
+	public static Object getIdentifier(SessionImplementor session, Object obj) {
+		if (obj == null) {
+			return null;
+		}
+
+		if (obj instanceof HibernateProxy) {
+			HibernateProxy hibernateProxy = (HibernateProxy) obj;
+			return hibernateProxy.getHibernateLazyInitializer().getIdentifier();
+		}
+
+
+		return session.getEntityPersister(null, obj).getIdentifier(obj, session.getEntityMode());
+	}
+
+	public static Object getTargetFromProxy(HibernateProxy proxy) {
+		if (!proxy.getHibernateLazyInitializer().isUninitialized()) {
+			return proxy.getHibernateLazyInitializer().getImplementation();
+		}
+
+		Session tempSession = proxy.getHibernateLazyInitializer().getSession().getFactory().openTemporarySession();
+		try {
+			proxy.getHibernateLazyInitializer().setSession((SessionImplementor) tempSession);
+			proxy.getHibernateLazyInitializer().initialize();
+			return proxy.getHibernateLazyInitializer().getImplementation();
+		} finally {
+			tempSession.close();
+		}
+	}
+
     public static boolean objectsEqual(Object obj1, Object obj2) {
         if (obj1 == null) {
             return obj2 == null;

Copied: core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reference/BidirectionalReference.java (from rev 16165, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/onetomany/BasicList.java)
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reference/BidirectionalReference.java	                        (rev 0)
+++ core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reference/BidirectionalReference.java	2009-04-22 08:38:05 UTC (rev 16393)
@@ -0,0 +1,150 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.envers.test.integration.reference;
+
+import org.hibernate.ejb.Ejb3Configuration;
+import org.hibernate.envers.test.AbstractEntityTest;
+import org.hibernate.envers.test.tools.TestTools;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import javax.persistence.EntityManager;
+import java.util.Arrays;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+public class BidirectionalReference extends AbstractEntityTest {
+    private Long set1_id;
+    private Long set2_id;
+
+    private Long g1_id;
+
+    public void configure(Ejb3Configuration cfg) {
+        cfg.addAnnotatedClass(GreetingPO.class);
+        cfg.addAnnotatedClass(GreetingSetPO.class);
+    }
+
+    @BeforeClass(dependsOnMethods = "init")
+    public void initData() {
+        EntityManager em = getEntityManager();
+
+        GreetingSetPO set1 = new GreetingSetPO();
+		set1.setName("a1");
+
+		GreetingSetPO set2 = new GreetingSetPO();
+		set2.setName("a2");
+
+        // Revision 1
+        em.getTransaction().begin();
+
+        em.persist(set1);
+        em.persist(set2);
+
+		set1_id = set1.getId();
+		set2_id = set2.getId();
+
+        em.getTransaction().commit();
+		em.clear();
+
+        // Revision 2
+        em.getTransaction().begin();
+
+        GreetingPO g1 = new GreetingPO();
+		g1.setGreeting("g1");
+		g1.setGreetingSet(em.getReference(GreetingSetPO.class, set1_id));
+
+        em.persist(g1);
+		g1_id = g1.getId();
+
+        em.getTransaction().commit();
+		em.clear();
+
+        // Revision 3
+        em.getTransaction().begin();
+
+        g1 = em.find(GreetingPO.class, g1_id);
+
+		g1.setGreetingSet(em.getReference(GreetingSetPO.class, set2_id));
+
+        em.getTransaction().commit();
+    }
+
+    @Test
+    public void testRevisionsCounts() { 
+        assert Arrays.asList(2, 3).equals(getAuditReader().getRevisions(GreetingPO.class, g1_id));
+
+        assert Arrays.asList(1, 2, 3).equals(getAuditReader().getRevisions(GreetingSetPO.class, set1_id));
+		assert Arrays.asList(1, 3).equals(getAuditReader().getRevisions(GreetingSetPO.class, set2_id));
+    }
+	
+    @Test
+    public void testHistoryOfG1() {
+		GreetingPO rev1 = getAuditReader().find(GreetingPO.class, g1_id, 1);
+		GreetingPO rev2 = getAuditReader().find(GreetingPO.class, g1_id, 2);
+		GreetingPO rev3 = getAuditReader().find(GreetingPO.class, g1_id, 3);
+
+        assert rev1 == null;
+        assert rev2.getGreetingSet().getName().equals("a1");
+		assert rev3.getGreetingSet().getName().equals("a2");
+    }
+
+	@Test
+    public void testHistoryOfSet1() {
+		GreetingSetPO rev1 = getAuditReader().find(GreetingSetPO.class, set1_id, 1);
+		GreetingSetPO rev2 = getAuditReader().find(GreetingSetPO.class, set1_id, 2);
+		GreetingSetPO rev3 = getAuditReader().find(GreetingSetPO.class, set1_id, 3);
+
+        assert rev1.getName().equals("a1");
+        assert rev2.getName().equals("a1");
+		assert rev3.getName().equals("a1");
+
+		GreetingPO g1 = new GreetingPO();
+		g1.setId(g1_id);
+		g1.setGreeting("g1");
+
+		assert rev1.getGreetings().size() == 0;
+		assert rev2.getGreetings().equals(TestTools.makeSet(g1));
+		assert rev3.getGreetings().size() == 0;
+    }
+
+	@Test
+    public void testHistoryOfSet2() {
+		GreetingSetPO rev1 = getAuditReader().find(GreetingSetPO.class, set2_id, 1);
+		GreetingSetPO rev2 = getAuditReader().find(GreetingSetPO.class, set2_id, 2);
+		GreetingSetPO rev3 = getAuditReader().find(GreetingSetPO.class, set2_id, 3);
+
+        assert rev1.getName().equals("a2");
+        assert rev2.getName().equals("a2");
+		assert rev3.getName().equals("a2");
+
+		GreetingPO g1 = new GreetingPO();
+		g1.setId(g1_id);
+		g1.setGreeting("g1");
+
+		assert rev1.getGreetings().size() == 0;
+		assert rev2.getGreetings().size() == 0;
+		assert rev3.getGreetings().equals(TestTools.makeSet(g1));
+    }
+}
\ No newline at end of file

Added: core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reference/GreetingPO.java
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reference/GreetingPO.java	                        (rev 0)
+++ core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reference/GreetingPO.java	2009-04-22 08:38:05 UTC (rev 16393)
@@ -0,0 +1,65 @@
+package org.hibernate.envers.test.integration.reference;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+
+import org.hibernate.envers.Audited;
+
+ at Entity
+ at Audited
+public class GreetingPO {
+	@Id
+	@GeneratedValue
+	private Long id;
+
+	private String theGreeting;
+
+	@ManyToOne
+	private GreetingSetPO greetingSet;
+
+	public Long getId() {
+		return id;
+	}
+
+	public void setId(Long id) {
+		this.id = id;
+	}
+
+	public String getGreeting() {
+		return theGreeting;
+	}
+
+	public void setGreeting(String greeting) {
+		this.theGreeting = greeting;
+	}
+
+	public GreetingSetPO getGreetingSet() {
+		return greetingSet;
+	}
+
+	public void setGreetingSet(GreetingSetPO greetingSet) {
+		this.greetingSet = greetingSet;
+	}
+
+	@Override
+	public boolean equals(Object o) {
+		if (this == o) return true;
+		if (!(o instanceof GreetingPO)) return false;
+
+		GreetingPO that = (GreetingPO) o;
+
+		if (id != null ? !id.equals(that.id) : that.id != null) return false;
+		if (theGreeting != null ? !theGreeting.equals(that.theGreeting) : that.theGreeting != null) return false;
+
+		return true;
+	}
+
+	@Override
+	public int hashCode() {
+		int result = id != null ? id.hashCode() : 0;
+		result = 31 * result + (theGreeting != null ? theGreeting.hashCode() : 0);
+		return result;
+	}
+}
\ No newline at end of file

Added: core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reference/GreetingSetPO.java
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reference/GreetingSetPO.java	                        (rev 0)
+++ core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reference/GreetingSetPO.java	2009-04-22 08:38:05 UTC (rev 16393)
@@ -0,0 +1,67 @@
+package org.hibernate.envers.test.integration.reference;
+
+import java.util.Set;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+
+import org.hibernate.envers.Audited;
+
+ at Entity
+ at Audited
+public class GreetingSetPO {
+	@Id
+	@GeneratedValue
+	private Long id;
+
+	private String name;
+
+	@OneToMany(mappedBy = "greetingSet")
+	private Set<GreetingPO> greetings;
+
+	public Long getId() {
+		return id;
+	}
+
+	public void setId(Long id) {
+		this.id = id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public Set<GreetingPO> getGreetings() {
+		return greetings;
+	}
+
+	public void setGreetings(Set<GreetingPO> greetings) {
+		this.greetings = greetings;
+	}
+
+	@Override
+	public boolean equals(Object o) {
+		if (this == o) return true;
+		if (!(o instanceof GreetingSetPO)) return false;
+
+		GreetingSetPO that = (GreetingSetPO) o;
+
+		if (id != null ? !id.equals(that.id) : that.id != null) return false;
+		if (name != null ? !name.equals(that.name) : that.name != null) return false;
+
+		return true;
+	}
+
+	@Override
+	public int hashCode() {
+		int result = id != null ? id.hashCode() : 0;
+		result = 31 * result + (name != null ? name.hashCode() : 0);
+		return result;
+	}
+}
\ No newline at end of file

Modified: core/trunk/envers/src/test/resources/testng.xml
===================================================================
--- core/trunk/envers/src/test/resources/testng.xml	2009-04-22 06:52:05 UTC (rev 16392)
+++ core/trunk/envers/src/test/resources/testng.xml	2009-04-22 08:38:05 UTC (rev 16393)
@@ -45,6 +45,7 @@
             <package name="org.hibernate.envers.test.integration.properties" />
             <package name="org.hibernate.envers.test.integration.query" />
             <package name="org.hibernate.envers.test.integration.query.ids" />
+            <package name="org.hibernate.envers.test.integration.reference" />
             <package name="org.hibernate.envers.test.integration.reventity" />
             <package name="org.hibernate.envers.test.integration.revfordate" />
             <package name="org.hibernate.envers.test.integration.sameids" />




More information about the hibernate-commits mailing list