OPENJPA-1505: allow duplicate entity listeners to be configurable

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@921538 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Fay Wang 2010-03-10 20:05:09 +00:00
parent 2798b0dd73
commit f69da24268
7 changed files with 128 additions and 10 deletions

View File

@ -28,6 +28,7 @@ import java.io.Serializable;
public class CallbackOptions implements Serializable {
private boolean _isPostPersistCallbackImmediate = false;
private boolean _allowsMultipleMethodsForSameCallback = false;
private boolean _allowsDuplicateListener = true;
/**
* Affirms if the post-persist callback is invoked as soon as a new instance
@ -64,4 +65,22 @@ public class CallbackOptions implements Serializable {
public void setAllowsMultipleMethodsForSameCallback(boolean flag) {
_allowsMultipleMethodsForSameCallback = flag;
}
/**
* Flags if duplicate listeners are allowed to handle the same
* callback event.
* Defaults to true.
*/
public boolean getAllowsDuplicateListener() {
return _allowsDuplicateListener;
}
/**
* Flags if duplicate listeners are allowed to handle the same
* callback event.
*/
public void setAllowsDuplicateListener(boolean flag) {
_allowsDuplicateListener = flag;
}
}

View File

@ -0,0 +1,49 @@
/*
* 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(value = {ListenerImpl.class, ListenerImpl.class})
public class DuplicateListenerEntity implements ListenerTestEntity {
@Id @GeneratedValue
private long id;
private int value;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}

View File

@ -23,6 +23,10 @@ import org.apache.openjpa.persistence.OpenJPAEntityManager;
public class TestEntityListeners extends SingleEMFTestCase {
private static final int ENTITY_LISTENER_ENTITY = 1;
private static final int GLOBAL_LISTENER_ENTITY = 2;
private static final int DUPLICATE_LISTENER_ENTITY = 3;
public void setUp() {
setUp(CLEAR_TABLES);
ListenerImpl.prePersistCount = 0;
@ -40,22 +44,38 @@ public class TestEntityListeners extends SingleEMFTestCase {
}
public void testEntityListeners() {
helper(true);
helper(ENTITY_LISTENER_ENTITY);
}
public void testGlobalListeners() {
helper(false);
helper(GLOBAL_LISTENER_ENTITY);
}
public void testDuplicateListeners() {
super.setUp(CLEAR_TABLES, DuplicateListenerEntity.class,
"openjpa.Callbacks", "AllowsDuplicateListener=false");
assertFalse(emf.getConfiguration().getCallbackOptionsInstance()
.getAllowsDuplicateListener());
helper(DUPLICATE_LISTENER_ENTITY);
}
public void helper(boolean entityListeners) {
public void helper(int entityListeners) {
OpenJPAEntityManager em = emf.createEntityManager();
try {
em.getTransaction().begin();
ListenerTestEntity o;
if (entityListeners)
ListenerTestEntity o = null;
switch (entityListeners) {
case ENTITY_LISTENER_ENTITY:
o = new EntityListenerEntity();
else
break;
case GLOBAL_LISTENER_ENTITY:
o = new GlobalListenerEntity();
break;
case DUPLICATE_LISTENER_ENTITY:
o = new DuplicateListenerEntity();
break;
}
em.persist(o);
assertStatus(1, 0, 0, 0, 0, 0, 0);
@ -68,11 +88,18 @@ public class TestEntityListeners extends SingleEMFTestCase {
em = emf.createEntityManager();
em.getTransaction().begin();
if (entityListeners)
switch (entityListeners) {
case ENTITY_LISTENER_ENTITY:
o = em.find(EntityListenerEntity.class, id);
else
break;
case GLOBAL_LISTENER_ENTITY:
o = em.find(GlobalListenerEntity.class, id);
break;
case DUPLICATE_LISTENER_ENTITY:
o = em.find(DuplicateListenerEntity.class, id);
break;
}
assertNotNull(o);
assertStatus(1, 1, 0, 0, 0, 0, 1);

View File

@ -34,6 +34,9 @@
<entity class="EntityListenerEntity">
<exclude-default-listeners/>
</entity>
<entity class="DuplicateListenerEntity">
<exclude-default-listeners/>
</entity>
<entity class="Message">
<exclude-default-listeners/>
</entity>

View File

@ -100,6 +100,7 @@
<mapping-file>META-INF/listener-orm.xml</mapping-file>
<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.Message</class>
<properties>
<property name="openjpa.jdbc.SynchronizeMappings"

View File

@ -855,10 +855,20 @@ public class AnnotationPersistenceMetaDataParser
private Collection<LifecycleCallbacks>[] parseEntityListeners
(ClassMetaData meta, EntityListeners listeners) {
Class<?>[] classes = listeners.value();
Collection<Class<?>> listenerColl = null;
Collection<LifecycleCallbacks>[] parsed = null;
for (Class<?> cls : classes)
for (Class<?> cls : classes) {
if (!_conf.getCallbackOptionsInstance().getAllowsDuplicateListener()) {
if (listenerColl == null)
listenerColl = new ArrayList<Class<?>>();
if (listenerColl.contains(cls))
continue;
listenerColl.add(cls);
}
parsed = parseCallbackMethods(cls, parsed, true, true,
getRepository());
}
return parsed;
}

View File

@ -208,6 +208,7 @@ public class XMLPersistenceMetaDataParser
private Class<?> _listener = null;
private Collection<LifecycleCallbacks>[] _callbacks = null;
private Collection<Class<?>> _listeners = null;
private int[] _highs = null;
private boolean _isXMLMappingMetaDataComplete = false;
@ -1831,6 +1832,14 @@ public class XMLPersistenceMetaDataParser
private boolean startEntityListener(Attributes attrs)
throws SAXException {
_listener = classForName(attrs.getValue("class"));
if (!_conf.getCallbackOptionsInstance().getAllowsDuplicateListener()) {
if (_listeners == null)
_listeners = new ArrayList<Class<?>>();
if (_listeners.contains(_listener))
return true;
_listeners.add(_listener);
}
boolean system = currentElement() == null;
Collection<LifecycleCallbacks>[] parsed =
AnnotationPersistenceMetaDataParser.parseCallbackMethods(_listener,