Hi Mark, I didn't get a chance to review this before you committed... I'm taking a closer look now. I'm queuing up some questions and will reply before end of day (hopefully)... Thanks!
Kevin On Thu, Dec 8, 2011 at 7:27 AM, <[email protected]> wrote: > 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 @PostLoad lifecycle event. > + * @param allow PostLoad lifecycle events to be triggered on a merge > operation > + */ > + public void setPostLoadOnMerge(boolean allow); > + > + /** > + * Force sending a @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 > + * @PostLoad get's executed. After I save my entity to the > database, the @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 @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> > > >
