mirror of https://github.com/apache/openjpa.git
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. git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@1211873 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
20772bc962
commit
4bffcc9c9a
|
@ -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;
|
||||
|
@ -214,6 +213,12 @@ public interface OpenJPAConfiguration
|
|||
public static final String OPTION_JDBC_CONNECTION =
|
||||
"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);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -594,6 +594,7 @@ public abstract class AbstractBrokerFactory
|
|||
broker.setMultithreaded(_conf.getMultithreaded());
|
||||
broker.setAutoDetach(_conf.getAutoDetachConstant());
|
||||
broker.setDetachState(_conf.getDetachStateInstance().getDetachState());
|
||||
broker.setPostLoadOnMerge(_conf.getPostLoadOnMerge());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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()]));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1485,4 +1485,13 @@ public class DelegatingBroker
|
|||
_broker.setAllowReferenceToSiblingContext(allow);
|
||||
}
|
||||
|
||||
public boolean getPostLoadOnMerge() {
|
||||
return _broker.getPostLoadOnMerge();
|
||||
}
|
||||
|
||||
public void setPostLoadOnMerge(boolean allow) {
|
||||
_broker.setPostLoadOnMerge(allow);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
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);
|
||||
boolean postLoadOnMerge = broker.getPostLoadOnMerge();
|
||||
if (_dirty.length() > 0 || postLoadOnMerge) {
|
||||
BitSet load = new BitSet(fields.length);
|
||||
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
|
||||
|
|
|
@ -157,6 +157,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.
|
||||
*/
|
||||
|
@ -3192,6 +3199,14 @@ public class StateManagerImpl
|
|||
_loaded.clear(field);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue