openjpa-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From strub...@apache.org
Subject svn commit: r1211873 - in /openjpa/trunk: openjpa-kernel/src/main/java/org/apache/openjpa/conf/ openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/ openjpa-persistence...
Date Thu, 08 Dec 2011 13:27:31 GMT
Author: struberg
Date: Thu Dec  8 13:27:31 2011
New Revision: 1211873

URL: http://svn.apache.org/viewvc?rev=1211873&view=rev
Log:
OPENJPA-1873 fix PostLoad entity listener behaviour

This fix introduces a new flag POST_LOAD_ON_MERGE wich is disabled
by default, retaining the old behaviour.
Enabling it will guarantee that the Entity posted to PostLoad entity 
listeners are always the one from the database. This fixes the old
habit that PostLoad will also get triggered (with false/mixed values)
for lazy loading, merging, etc.


Added:
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/EntityListenerPostLoadTest.java
  (with props)
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/PostLoadListenerEntity.java
  (with props)
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/PostLoadListenerImpl.java
  (with props)
Modified:
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfiguration.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedStateManager.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/conf/TestOpenJPAConfiguration.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/resources/META-INF/persistence.xml

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfiguration.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfiguration.java?rev=1211873&r1=1211872&r2=1211873&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfiguration.java
(original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfiguration.java
Thu Dec  8 13:27:31 2011
@@ -21,7 +21,6 @@ package org.apache.openjpa.conf;
 import java.util.Collection;
 import java.util.Map;
 
-import org.apache.openjpa.kernel.AuditManager;
 import org.apache.openjpa.audit.Auditor;
 import org.apache.openjpa.datacache.CacheDistributionPolicy;
 import org.apache.openjpa.datacache.DataCache;
@@ -215,6 +214,12 @@ public interface OpenJPAConfiguration
         "openjpa.option.JDBCConnection";
 
     /**
+     * Option for enable fire @PostLoad events on merge operations
+     */
+    public static final String OPTION_POSTLOAD_ON_MERGE =
+        "openjpa.option.PostLoadOnMerge";
+
+    /**
      * Return the set of option strings supported by this runtime. This set
      * is mutable.
      */
@@ -242,7 +247,7 @@ public interface OpenJPAConfiguration
      * This change will trigger all registered Product Derivations to mutate 
      * other configuration properties.
      *
-     * @param fullname of the specification that possibly encodes major and
+     * @param spec fullname of the specification that possibly encodes major and
      * minor version information. For encoding format
      * @see Specification
      * 
@@ -258,7 +263,7 @@ public interface OpenJPAConfiguration
      * This change will trigger all registered Product Derivations to mutate 
      * other configuration properties.
      *
-     * @param fullname of the specification that possibly encodes major and
+     * @param spec fullname of the specification that possibly encodes major and
      * minor version information. For encoding format
      * @see Specification
      * 
@@ -1894,6 +1899,24 @@ public interface OpenJPAConfiguration
      * @since 2.2.0
      */
     public void setAuditor(String s);
+
+     /**
+      * Whether to send @PostLoad events on a merge operation.
+      * @since 2.2.0
+      */
+     public boolean getPostLoadOnMerge();
+
+     /**
+      * Whether to send @PostLoad events on a merge operation.
+      * @since 2.2.0
+      */
+     public void setPostLoadOnMerge(boolean postLoadOnMerge);
+
+     /**
+      * Whether to send @PostLoad events on a merge operation.
+      * @since 2.2.0
+      */
+     public void setPostLoadOnMerge(Boolean postLoadOnMerge);
     
 }
 

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java?rev=1211873&r1=1211872&r2=1211873&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java
(original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java
Thu Dec  8 13:27:31 2011
@@ -176,6 +176,7 @@ public class OpenJPAConfigurationImpl
     public BooleanValue dynamicEnhancementAgent;
     public ObjectValue instrumentationManager;
     public PluginListValue instrumentationProviders;
+    public BooleanValue postLoadOnMerge;
     
     // custom values
     public BrokerFactoryValue brokerFactoryPlugin;
@@ -397,6 +398,10 @@ public class OpenJPAConfigurationImpl
         optimistic.setDefault("true");
         optimistic.set(true);
 
+        postLoadOnMerge = addBoolean("PostLoadOnMerge");
+        postLoadOnMerge.setDefault("false");
+        postLoadOnMerge.set(false);
+
         autoClear = addInt("AutoClear");
         aliases =
             new String[] { "datastore",
@@ -612,7 +617,8 @@ public class OpenJPAConfigurationImpl
         supportedOptions.add(OPTION_VALUE_AUTOASSIGN);
         supportedOptions.add(OPTION_VALUE_INCREMENT);
         supportedOptions.add(OPTION_DATASTORE_CONNECTION);
-        
+        supportedOptions.add(OPTION_POSTLOAD_ON_MERGE);
+
         if (derivations)
             ProductDerivations.beforeConfigurationLoad(this);
         if (loadGlobals)
@@ -1836,5 +1842,19 @@ public class OpenJPAConfigurationImpl
     public void setAuditor(String auditor) {
     	auditorPlugin.setString(auditor);
     }
+
+    public boolean getPostLoadOnMerge() {
+        return postLoadOnMerge.get();
+    }
+
+    public void setPostLoadOnMerge(boolean postLoadOnMerge) {
+        this.postLoadOnMerge.set(postLoadOnMerge);
+    }
+
+    public void setPostLoadOnMerge(Boolean postLoadOnMerge) {
+        if (postLoadOnMerge != null)
+            setPostLoadOnMerge(postLoadOnMerge.booleanValue());
+    }
+
 }
 

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java?rev=1211873&r1=1211872&r2=1211873&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java
(original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java
Thu Dec  8 13:27:31 2011
@@ -594,6 +594,7 @@ public abstract class AbstractBrokerFact
         broker.setMultithreaded(_conf.getMultithreaded());
         broker.setAutoDetach(_conf.getAutoDetachConstant());
         broker.setDetachState(_conf.getDetachStateInstance().getDetachState());
+        broker.setPostLoadOnMerge(_conf.getPostLoadOnMerge());
     }
 
     /**

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java?rev=1211873&r1=1211872&r2=1211873&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java Thu
Dec  8 13:27:31 2011
@@ -241,6 +241,7 @@ public class BrokerImpl
     private boolean _cacheFinderQuery = true;
     private boolean _suppressBatchOLELogging = false;
     private boolean _allowReferenceToSiblingContext = false;
+    private boolean _postLoadOnMerge = false;
     
     // status
     private int _flags = 0;
@@ -5199,27 +5200,33 @@ public class BrokerImpl
         return ((_flags & FLAG_FLUSHING) != 0);
     }
     
+     public boolean getPostLoadOnMerge() {
+         return _postLoadOnMerge;
+     }
+
+     public void setPostLoadOnMerge(boolean allow) {
+         _postLoadOnMerge = allow;
+     }
     
-    
-        /**
-         * Asserts consistencey of given automatic detachment option value.
-         */
-        private void assertAutoDetachValue(int value) {
-           if (((value & AutoDetach.DETACH_NONE) != 0) && (value != AutoDetach.DETACH_NONE))
{
-                   throw new UserException(_loc.get("detach-none-exclusive", toAutoDetachString(value)));
-           }
-        }
-    
-        /**
-         * Generates a user-readable String from the given integral value of AutoDetach options.
-         */
-        private String toAutoDetachString(int value) {
-           List<String> result = new ArrayList<String>();
-           for (int i = 0; i < AutoDetach.values.length; i++) {
-                   if ((value & AutoDetach.values[i]) != 0) {
-                           result.add(AutoDetach.names[i]);
-                   }
-           }
-           return Arrays.toString(result.toArray(new String[result.size()]));
-        }
+    /**
+     * Asserts consistencey of given automatic detachment option value.
+     */
+    private void assertAutoDetachValue(int value) {
+       if (((value & AutoDetach.DETACH_NONE) != 0) && (value != AutoDetach.DETACH_NONE))
{
+               throw new UserException(_loc.get("detach-none-exclusive", toAutoDetachString(value)));
+       }
+    }
+
+    /**
+     * Generates a user-readable String from the given integral value of AutoDetach options.
+     */
+    private String toAutoDetachString(int value) {
+       List<String> result = new ArrayList<String>();
+       for (int i = 0; i < AutoDetach.values.length; i++) {
+               if ((value & AutoDetach.values[i]) != 0) {
+                       result.add(AutoDetach.names[i]);
+               }
+       }
+       return Arrays.toString(result.toArray(new String[result.size()]));
+    }
 }

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java?rev=1211873&r1=1211872&r2=1211873&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java
(original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java
Thu Dec  8 13:27:31 2011
@@ -1485,4 +1485,13 @@ public class DelegatingBroker
         _broker.setAllowReferenceToSiblingContext(allow);
     }
 
+    public boolean getPostLoadOnMerge() {
+        return _broker.getPostLoadOnMerge();
+    }
+
+    public void setPostLoadOnMerge(boolean allow) {
+        _broker.setPostLoadOnMerge(allow);
+    }
+
+
 }

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedStateManager.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedStateManager.java?rev=1211873&r1=1211872&r2=1211873&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedStateManager.java
(original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedStateManager.java
Thu Dec  8 13:27:31 2011
@@ -28,9 +28,11 @@ import java.util.Map;
 import org.apache.openjpa.conf.Compatibility;
 import org.apache.openjpa.enhance.PersistenceCapable;
 import org.apache.openjpa.enhance.StateManager;
+import org.apache.openjpa.event.LifecycleEventManager;
 import org.apache.openjpa.lib.util.Localizer;
 import java.util.concurrent.locks.ReentrantLock;
 import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.FetchGroup;
 import org.apache.openjpa.meta.FieldMetaData;
 import org.apache.openjpa.meta.JavaTypes;
 import org.apache.openjpa.meta.ValueMetaData;
@@ -128,45 +130,62 @@ public class DetachedStateManager
 
         // pre-load for efficiency: current field values for restore, dependent
         // for delete
-        FieldMetaData[] fields = sm.getMetaData().getFields(); 
+        FieldMetaData[] fields = sm.getMetaData().getFields();
         int restore = broker.getRestoreState();
-        if (_dirty.length() > 0) {
+
+        boolean postLoadOnMerge = broker.getPostLoadOnMerge();
+        if (_dirty.length() > 0 || postLoadOnMerge) {
             BitSet load = new BitSet(fields.length);
-            for (int i = 0; i < fields.length; i++) {
-                if (!_dirty.get(i))
-                    continue;
-
-                switch (fields[i].getDeclaredTypeCode()) {
-                    case JavaTypes.ARRAY:
-                    case JavaTypes.COLLECTION:
-                        if (restore == RestoreState.RESTORE_ALL
-                            || fields[i].getElement().getCascadeDelete()
-                            == ValueMetaData.CASCADE_AUTO)
-                            load.set(i);
-                        break;
-                    case JavaTypes.MAP:
-                        if (restore == RestoreState.RESTORE_ALL
-                            || fields[i].getElement().getCascadeDelete()
-                            == ValueMetaData.CASCADE_AUTO
-                            || fields[i].getKey().getCascadeDelete()
-                            == ValueMetaData.CASCADE_AUTO)
-                            load.set(i);
-                        break;
-                    default:
-                        if (restore != RestoreState.RESTORE_NONE
-                            || fields[i].getCascadeDelete()
-                            == ValueMetaData.CASCADE_AUTO)
-                            load.set(i);
+            if (postLoadOnMerge && broker.getLifecycleEventManager().hasLoadListeners(pc,
meta)) {
+                // load all fields
+                // this will automatically lead to invoking the PostLoad lifecycle event
+                // when the last field got set
+                // @see StateManagerImpl#postLoad(String, FetchConfiguration)
+                load.set(0, fields.length);
+            }
+            else {
+                for (int i = 0; i < fields.length; i++) {
+                    if (!_dirty.get(i))
+                        continue;
+
+                    switch (fields[i].getDeclaredTypeCode()) {
+                        case JavaTypes.ARRAY:
+                        case JavaTypes.COLLECTION:
+                            if (restore == RestoreState.RESTORE_ALL
+                                || fields[i].getElement().getCascadeDelete()
+                                == ValueMetaData.CASCADE_AUTO)
+                                load.set(i);
+                            break;
+                        case JavaTypes.MAP:
+                            if (restore == RestoreState.RESTORE_ALL
+                                || fields[i].getElement().getCascadeDelete()
+                                == ValueMetaData.CASCADE_AUTO
+                                || fields[i].getKey().getCascadeDelete()
+                                == ValueMetaData.CASCADE_AUTO)
+                                load.set(i);
+                            break;
+                        default:
+                            if (restore != RestoreState.RESTORE_NONE
+                                || fields[i].getCascadeDelete()
+                                == ValueMetaData.CASCADE_AUTO)
+                                load.set(i);
+                    }
                 }
             }
+
+            if (!postLoadOnMerge) {
+                // prevent PostLoad callbacks even for the load operation
+                sm.setPostLoadCallback(false);
+            }
             FetchConfiguration fc = broker.getFetchConfiguration();
             sm.loadFields(load, fc, fc.getWriteLockLevel(), null);
-        }        
+        }
         Object origVersion = sm.getVersion();
         sm.setVersion(_version);
 
         BitSet loaded = sm.getLoaded();
         int set = StateManager.SET_ATTACH;
+        sm.setPostLoadCallback(false);
         for (int i = 0; i < fields.length; i++) {
             if (!_loaded.get(i))
                 continue;
@@ -214,8 +233,8 @@ public class DetachedStateManager
                     break;
                 case JavaTypes.SHORT:
                     if (_dirty.get(i))
-                        sm.settingShortField(pc, i, (!loaded.get(i)) ? (short) 0
-                            : sm.fetchShortField(i), (short) longval, set);
+                        sm.settingShortField(pc, i, 
+                            (!loaded.get(i)) ? (short) 0 : sm.fetchShortField(i), (short)
longval, set);
                     else
                         sm.storeShortField(i, (short) longval);
                     break;
@@ -299,6 +318,7 @@ public class DetachedStateManager
                     objval = null;
             }
         }
+        sm.setPostLoadCallback(true);
         pc.pcReplaceStateManager(sm);
 
         // if we were clean at least make sure a version check is done to

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java?rev=1211873&r1=1211872&r2=1211873&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java
(original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java
Thu Dec  8 13:27:31 2011
@@ -158,6 +158,13 @@ public class StateManagerImpl
     private transient ReentrantLock _instanceLock = null;
 
     /**
+     * <p>set to <code>false</code> to prevent the postLoad method from
+     * sending lifecycle callback events.</p>
+     * <p>Callbacks are enabled by default</>
+     */
+    private boolean postLoadCallback = true;
+
+    /**
      * Constructor; supply id, type metadata, and owning persistence manager.
      */
     protected StateManagerImpl(Object id, ClassMetaData meta, 
@@ -3193,6 +3200,14 @@ public class StateManagerImpl
     }
 
     /**
+     * Set to <code>false</code> to prevent the postLoad method from
+     * sending lifecycle callback events.
+     */
+    public void setPostLoadCallback(boolean enabled) {
+        this.postLoadCallback = enabled;
+    }
+
+    /**
      * Perform post-load steps, including the post load callback.
      * We have to check the dfg after all field loads because it might be
      * loaded in multiple steps when paging is involved; the initial load
@@ -3254,8 +3269,8 @@ public class StateManagerImpl
                 return false;
 
         _flags |= FLAG_LOADED;
-        _broker.fireLifecycleEvent(getManagedInstance(), fetch, _meta, 
-        	LifecycleEvent.AFTER_LOAD);
+        if (postLoadCallback)
+            _broker.fireLifecycleEvent(getManagedInstance(), fetch, _meta, LifecycleEvent.AFTER_LOAD);
         return true;
     }
 

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java?rev=1211873&r1=1211872&r2=1211873&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java
(original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java
Thu Dec  8 13:27:31 2011
@@ -531,4 +531,22 @@ public interface StoreContext {
      * @since 2.1
      */
     public boolean getAllowReferenceToSiblingContext();
+
+
+    /**
+     * Set to <code>true</code> if the merge operation should trigger
+     * a &#064;PostLoad lifecycle event.
+     * @param allow PostLoad lifecycle events to be triggered on a merge operation
+     */
+    public void setPostLoadOnMerge(boolean allow);
+
+    /**
+     * Force sending a &#064;PostLoad lifecycle event while merging.
+     *
+     * @return <code>false</code> by default
+     *
+     * @since 2.2
+     */
+    public boolean getPostLoadOnMerge();
+
 }

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/EntityListenerPostLoadTest.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/EntityListenerPostLoadTest.java?rev=1211873&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/EntityListenerPostLoadTest.java
(added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/EntityListenerPostLoadTest.java
Thu Dec  8 13:27:31 2011
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.callbacks;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+public class EntityListenerPostLoadTest extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp(CLEAR_TABLES);
+    }
+
+    @Override
+    protected String getPersistenceUnitName() {
+        return "listener-pu";
+    }
+
+    /**
+     * If an entity gets merged it is first read from the database prior to the update. In
this read step, the
+     * &#064;PostLoad get's executed. After I save my entity to the database, the &#064;PostLoad
following merge should
+     * return exactly the value stored to the database. Even if the value got changed locally
in the meantime.
+     */
+    public void testPostLoadValues() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        try {
+            em.getTransaction().begin();
+
+            PostLoadListenerEntity entity = null;
+
+            entity = new PostLoadListenerEntity();
+            entity.setValue("val1");
+
+            em.persist(entity);
+            em.getTransaction().commit();
+
+            // close the EntityManager so our entity is now detached
+            em.close();
+
+            // reopen a new EntityManager
+            em = emf.createEntityManager();
+            assertTrue(em.isDetached(entity));
+
+            em.getTransaction().begin();
+            // entity = em.find(PostLoadListenerEntity.class, entity.getId());
+            entity = em.find(PostLoadListenerEntity.class, entity.getId());
+            assertNotNull(entity);
+
+            // the merge invoked a PostLoad, so this should now be 'val1'
+            assertEquals("val1", PostLoadListenerImpl.postLoadValue);
+
+            em.getTransaction().commit();
+
+            // close the EntityManager so our entity is now detached again
+            em.close();
+
+            // reopen a new EntityManager
+            em = emf.createEntityManager();
+            em.getTransaction().begin();
+            
+            assertTrue(em.isDetached(entity));
+            
+            entity.setValue("val2");
+            //X entity.setValue2("val2");
+
+            entity = em.merge(entity);
+
+            // the merge invoked a PostLoad, and this should now STILL be 'val1'
+            assertEquals("val1", PostLoadListenerImpl.postLoadValue);
+            em.getTransaction().commit();
+
+            // close the EntityManager so our entity is now detached again
+            em.close();
+
+            // reopen a new EntityManager
+            em = emf.createEntityManager();
+            em.getTransaction().begin();
+            entity.setValue("val3");
+
+            entity = em.merge(entity);
+
+            // the merge invoked a PostLoad, and this should now STILL be 'val1'
+            assertEquals("val2", PostLoadListenerImpl.postLoadValue);
+            em.getTransaction().commit();
+
+        } finally {
+            if (em != null && em.getTransaction().isActive())
+                em.getTransaction().rollback();
+            if (em != null && em.isOpen())
+                em.close();
+        }
+
+    }
+}

Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/EntityListenerPostLoadTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/PostLoadListenerEntity.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/PostLoadListenerEntity.java?rev=1211873&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/PostLoadListenerEntity.java
(added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/PostLoadListenerEntity.java
Thu Dec  8 13:27:31 2011
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.callbacks;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.GeneratedValue;
+import javax.persistence.EntityListeners;
+
+
+@Entity
+@EntityListeners({PostLoadListenerImpl.class})
+public class PostLoadListenerEntity {
+
+    @Id @GeneratedValue
+    private long id;
+
+    private String value;
+    
+    // those fields are important for the test since
+    // OpenJPA will load the full Table at once if you remove them  
+    private String value2;
+
+        
+    public long getId() {
+        return id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public String getValue2() {
+        return value2;
+    }
+
+    public void setValue2(String value2) {
+        this.value2 = value2;
+    }
+}

Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/PostLoadListenerEntity.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/PostLoadListenerImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/PostLoadListenerImpl.java?rev=1211873&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/PostLoadListenerImpl.java
(added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/PostLoadListenerImpl.java
Thu Dec  8 13:27:31 2011
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.callbacks;
+
+import javax.persistence.PostLoad;
+
+/**
+ * JPA Listener which maintains changelog information of the {@link PostLoadListenerEntity}.
+ * The &#064;PostLoad gets called once the entity is being loaded from the database.
+ * This happens either if the entity get's loaded freshly into the EntityManager, or 
+ * while performing a call to EntityManager#merge(entity)
+ */
+public class PostLoadListenerImpl {
+
+    static String postLoadValue;
+    
+    @PostLoad
+    public void postLoad(Object o) {
+        PostLoadListenerEntity ple = (PostLoadListenerEntity) o;
+        
+        postLoadValue = ple.getValue();
+    }
+}

Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/PostLoadListenerImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/conf/TestOpenJPAConfiguration.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/conf/TestOpenJPAConfiguration.java?rev=1211873&r1=1211872&r2=1211873&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/conf/TestOpenJPAConfiguration.java
(original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/conf/TestOpenJPAConfiguration.java
Thu Dec  8 13:27:31 2011
@@ -70,6 +70,7 @@ public class TestOpenJPAConfiguration
         assertEquals(cfactory, conf.getConnectionFactory());
         assertEquals(cfactory2, conf.getConnectionFactory2());
         assertEquals(false, conf.getOptimistic());
+        assertEquals(false, conf.getPostLoadOnMerge());
         assertEquals(503, conf.getLockTimeout());
         assertEquals(1500, conf.getQueryTimeout());
 

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/resources/META-INF/persistence.xml
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/resources/META-INF/persistence.xml?rev=1211873&r1=1211872&r2=1211873&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/resources/META-INF/persistence.xml (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/resources/META-INF/persistence.xml Thu
Dec  8 13:27:31 2011
@@ -101,8 +101,10 @@
         <class>org.apache.openjpa.persistence.callbacks.EntityListenerEntity</class>
         <class>org.apache.openjpa.persistence.callbacks.GlobalListenerEntity</class>
         <class>org.apache.openjpa.persistence.callbacks.DuplicateListenerEntity</class>
+        <class>org.apache.openjpa.persistence.callbacks.PostLoadListenerEntity</class>
         <class>org.apache.openjpa.persistence.callbacks.Message</class>
         <properties>
+            <property name="openjpa.PostLoadOnMerge" value="true"/>
             <property name="openjpa.jdbc.SynchronizeMappings"
                   value="buildSchema(ForeignKeys=true)"/>
         </properties>



Mime
View raw message