OPENJPA-506. svn merge -c 618821 ../../trunk. Oddly, the TCK was passing on this branch; maybe trunk and 1.0.x have different TCK versions?

git-svn-id: https://svn.apache.org/repos/asf/openjpa/branches/1.0.x@618834 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Patrick Linskey 2008-02-06 00:09:28 +00:00
parent 78e258706d
commit f38d30496b
13 changed files with 524 additions and 5 deletions

View File

@ -491,6 +491,42 @@ public class LifecycleEventManager
((AttachListener) listener).afterAttach(ev); ((AttachListener) listener).afterAttach(ev);
} }
break; break;
case LifecycleEvent.AFTER_PERSIST_PERFORMED:
if (responds || listener instanceof PostPersistListener)
{
if (mock)
return Boolean.TRUE;
if (ev == null)
ev = new LifecycleEvent(source, rel, type);
((PostPersistListener) listener)
.afterPersistPerformed(ev);
}
break;
case LifecycleEvent.BEFORE_UPDATE:
case LifecycleEvent.AFTER_UPDATE_PERFORMED:
if (responds || listener instanceof UpdateListener) {
if (mock)
return Boolean.TRUE;
if (ev == null)
ev = new LifecycleEvent(source, rel, type);
if (type == LifecycleEvent.BEFORE_UPDATE)
((UpdateListener) listener).beforeUpdate(ev);
else
((UpdateListener) listener)
.afterUpdatePerformed(ev);
}
break;
case LifecycleEvent.AFTER_DELETE_PERFORMED:
if (responds || listener instanceof PostDeleteListener){
if (mock)
return Boolean.TRUE;
if (ev == null)
ev = new LifecycleEvent(source, rel, type);
((PostDeleteListener) listener)
.afterDeletePerformed(ev);
}
break;
default: default:
if (_log.isWarnEnabled()) if (_log.isWarnEnabled())
_log.warn(_loc.get("unknown-lifecycle-event", _log.warn(_loc.get("unknown-lifecycle-event",

View File

@ -0,0 +1,33 @@
/*
* 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.event;
/**
* @since 1.1.0
*/
public interface PostDeleteListener {
/**
* Receives notifications before an update is performed. Differs from
* {@link DeleteListener#afterDelete(LifecycleEvent)} in that the latter
* is called after the delete operation, whereas this is called after the
* delete statements have been sent to the data store.
*/
public void afterDeletePerformed(LifecycleEvent event);
}

View File

@ -0,0 +1,33 @@
/*
* 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.event;
/**
* @since 1.1.0
*/
public interface PostPersistListener {
/**
* Receives notifications after a persist operation has been written to the
* data store. Differs from {@link PersistListener#afterPersist} in that
* the latter is called at the end of the persist() operation itself, not
* after the flush.
*/
public void afterPersistPerformed(LifecycleEvent event);
}

View File

@ -0,0 +1,42 @@
/*
* 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.event;
/**
* @since 1.1.0
*/
public interface UpdateListener {
/**
* Receives notifications before an update is performed. Differs from
* {@link StoreListener#beforeStore} in that the latter is called for
* updated and new records, whereas this is only invoked for updated
* records.
*/
public void beforeUpdate(LifecycleEvent event);
/**
* Receives notifications before an update is performed. Differs from
* {@link StoreListener#afterStore} in that the latter is called for
* updated and new records, whereas this is only invoked for updated
* records, and that this is called after the record is actually flushed
* to the store.
*/
public void afterUpdatePerformed(LifecycleEvent event);
}

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)
public class EntityListenerEntity 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

@ -0,0 +1,50 @@
/*
* 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;
import org.apache.openjpa.persistence.callbacks.ListenerImpl;
@Entity
public class GlobalListenerEntity 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

@ -0,0 +1,73 @@
/*
* 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.PrePersist;
import javax.persistence.PostPersist;
import javax.persistence.PostLoad;
import javax.persistence.PreUpdate;
import javax.persistence.PostUpdate;
import javax.persistence.PreRemove;
import javax.persistence.PostRemove;
public class ListenerImpl {
static int prePersistCount;
static int postPersistCount;
static int preUpdateCount;
static int postUpdateCount;
static int preRemoveCount;
static int postRemoveCount;
static int postLoadCount;
@PrePersist
public void prePersist(Object o) {
prePersistCount++;
}
@PostPersist
public void postPersist(Object o) {
postPersistCount++;
}
@PostLoad
public void postLoad(Object o) {
postLoadCount++;
}
@PreUpdate
public void preUpdate(Object o) {
preUpdateCount++;
}
@PostUpdate
public void postUpdate(Object o) {
postUpdateCount++;
}
@PreRemove
public void preRemove(Object o) {
preRemoveCount++;
}
@PostRemove
public void postRemove(Object o) {
postRemoveCount++;
}
}

View File

@ -0,0 +1,28 @@
/*
* 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;
public interface ListenerTestEntity {
public long getId();
public int getValue();
public void setValue(int val);
}

View File

@ -0,0 +1,114 @@
/*
* 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.test.SingleEMFTestCase;
import org.apache.openjpa.persistence.OpenJPAEntityManager;
public class TestEntityListeners extends SingleEMFTestCase {
public void setUp() {
setUp(CLEAR_TABLES);
ListenerImpl.prePersistCount = 0;
ListenerImpl.postPersistCount = 0;
ListenerImpl.preUpdateCount = 0;
ListenerImpl.postUpdateCount = 0;
ListenerImpl.preRemoveCount = 0;
ListenerImpl.postRemoveCount = 0;
ListenerImpl.postLoadCount = 0;
}
@Override
protected String getPersistenceUnitName() {
return "listener-pu";
}
public void testEntityListeners() {
helper(true);
}
public void testGlobalListeners() {
helper(false);
}
public void helper(boolean entityListeners) {
OpenJPAEntityManager em = emf.createEntityManager();
try {
em.getTransaction().begin();
ListenerTestEntity o;
if (entityListeners)
o = new EntityListenerEntity();
else
o = new GlobalListenerEntity();
em.persist(o);
assertStatus(1, 0, 0, 0, 0, 0, 0);
em.getTransaction().commit();
long id = o.getId();
em.close();
assertStatus(1, 1, 0, 0, 0, 0, 0);
em = emf.createEntityManager();
em.getTransaction().begin();
if (entityListeners)
o = em.find(EntityListenerEntity.class, id);
else
o = em.find(GlobalListenerEntity.class, id);
assertNotNull(o);
assertStatus(1, 1, 0, 0, 0, 0, 1);
o.setValue(o.getValue() + 1);
em.flush();
assertStatus(1, 1, 1, 1, 0, 0, 1);
em.remove(o);
assertStatus(1, 1, 1, 1, 1, 0, 1);
em.getTransaction().commit();
assertStatus(1, 1, 1, 1, 1, 1, 1);
em.close();
} finally {
if (em != null && em.getTransaction().isActive())
em.getTransaction().rollback();
if (em != null && em.isOpen())
em.close();
}
}
private void assertStatus(
int prePersist, int postPersist,
int preUpdate, int postUpdate,
int preRemove, int postRemove,
int postLoad) {
assertEquals(prePersist, ListenerImpl.prePersistCount);
assertEquals(postPersist, ListenerImpl.postPersistCount);
assertEquals(preUpdate, ListenerImpl.preUpdateCount);
assertEquals(postUpdate, ListenerImpl.postUpdateCount);
assertEquals(preRemove, ListenerImpl.preRemoveCount);
assertEquals(postRemove, ListenerImpl.postRemoveCount);
assertEquals(postLoad, ListenerImpl.postLoadCount);
}
}

View File

@ -91,7 +91,11 @@ public abstract class PersistenceTestCase
} }
return (OpenJPAEntityManagerFactorySPI) Persistence. return (OpenJPAEntityManagerFactorySPI) Persistence.
createEntityManagerFactory("test", map); createEntityManagerFactory(getPersistenceUnitName(), map);
}
protected String getPersistenceUnitName() {
return "test";
} }
@Override @Override

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
version="1.0">
<package>org.apache.openjpa.persistence.callbacks</package>
<entity class="EntityListenerEntity">
<exclude-default-listeners>true</exclude-default-listeners>
</entity>
<persistence-unit-metadata>
<persistence-unit-defaults>
<entity-listeners>
<entity-listener class="ListenerImpl">
</entity-listener>
</entity-listeners>
</persistence-unit-defaults>
</persistence-unit-metadata>
</entity-mappings>

View File

@ -63,4 +63,14 @@
value="DriverClassName=not.a.real.Driver,Url=jdbc:notreal://"/> value="DriverClassName=not.a.real.Driver,Url=jdbc:notreal://"/>
</properties> </properties>
</persistence-unit> </persistence-unit>
<persistence-unit name="listener-pu">
<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>
<properties>
<property name="openjpa.jdbc.SynchronizeMappings"
value="buildSchema(ForeignKeys=true)"/>
</properties>
</persistence-unit>
</persistence> </persistence>

View File

@ -27,13 +27,16 @@ import org.apache.openjpa.event.LifecycleEvent;
import org.apache.openjpa.event.LifecycleEventManager; import org.apache.openjpa.event.LifecycleEventManager;
import org.apache.openjpa.event.LoadListener; import org.apache.openjpa.event.LoadListener;
import org.apache.openjpa.event.PersistListener; import org.apache.openjpa.event.PersistListener;
import org.apache.openjpa.event.StoreListener; import org.apache.openjpa.event.PostPersistListener;
import org.apache.openjpa.event.UpdateListener;
import org.apache.openjpa.event.PostDeleteListener;
import org.apache.openjpa.lib.util.Localizer; import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.util.CallbackException; import org.apache.openjpa.util.CallbackException;
class PersistenceListenerAdapter class PersistenceListenerAdapter
implements LifecycleEventManager.ListenerAdapter, PersistListener, implements LifecycleEventManager.ListenerAdapter, PersistListener,
LoadListener, StoreListener, DeleteListener { PostPersistListener, LoadListener, UpdateListener, DeleteListener,
PostDeleteListener {
private static final Localizer _loc = Localizer.forPackage private static final Localizer _loc = Localizer.forPackage
(PersistenceListenerAdapter.class); (PersistenceListenerAdapter.class);
@ -83,6 +86,10 @@ class PersistenceListenerAdapter
} }
public void afterPersist(LifecycleEvent event) { public void afterPersist(LifecycleEvent event) {
throw new UnsupportedOperationException();
}
public void afterPersistPerformed(LifecycleEvent event) {
makeCallback(event); makeCallback(event);
} }
@ -94,11 +101,11 @@ class PersistenceListenerAdapter
makeCallback(event); makeCallback(event);
} }
public void beforeStore(LifecycleEvent event) { public void beforeUpdate(LifecycleEvent event) {
makeCallback(event); makeCallback(event);
} }
public void afterStore(LifecycleEvent event) { public void afterUpdatePerformed(LifecycleEvent event) {
makeCallback(event); makeCallback(event);
} }
@ -107,6 +114,10 @@ class PersistenceListenerAdapter
} }
public void afterDelete(LifecycleEvent event) { public void afterDelete(LifecycleEvent event) {
throw new UnsupportedOperationException();
}
public void afterDeletePerformed(LifecycleEvent event) {
makeCallback(event); makeCallback(event);
} }
} }