Author: ppoddar
Date: Mon Oct 12 18:48:10 2009
New Revision: 824454
URL: http://svn.apache.org/viewvc?rev=824454&view=rev
Log:
OPENJPA-1341: PostRemove callback trigger points
Added:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/PostRemoveCallbackEntity.java
(with props)
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestPostRemove.java
(with props)
Modified:
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jta/ContainerTest.java
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/SingleEMFTestCase.java
openjpa/trunk/openjpa-persistence-jdbc/src/test/resources/META-INF/persistence.xml
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=824454&r1=824453&r2=824454&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
Mon Oct 12 18:48:10 2009
@@ -1935,7 +1935,7 @@
if ((_autoDetach & DETACH_COMMIT) != 0)
detachAllInternal(null);
- else if (status == Status.STATUS_ROLLEDBACK
+ else if (status == Status.STATUS_ROLLEDBACK
&& (_autoDetach & DETACH_ROLLBACK) != 0) {
detachAllInternal(null);
}
@@ -2313,7 +2313,7 @@
_derefCache = null;
}
- // peform commit or rollback state transitions on each instance
+ // perform commit or rollback state transitions on each instance
StateManagerImpl sm;
for (Iterator itr = transStates.iterator(); itr.hasNext();) {
sm = (StateManagerImpl) itr.next();
@@ -2323,8 +2323,13 @@
// (and therefore deleted) to un-deref
sm.setDereferencedDependent(false, false);
sm.rollback();
- } else
+ } else {
+ if (sm.getPCState() == PCState.PNEWDELETED ||
sm.getPCState() == PCState.PDELETED) {
+ fireLifecycleEvent(sm.getPersistenceCapable(), null,
sm.getMetaData(),
+ LifecycleEvent.AFTER_DELETE_PERFORMED);
+ }
sm.commit();
+ }
} catch (RuntimeException re) {
exceps = add(exceps, re);
}
@@ -3907,7 +3912,7 @@
/**
* Return a copy of all transactional state managers.
*/
- protected Collection getTransactionalStates() {
+ protected Collection<StateManagerImpl> getTransactionalStates() {
if (!hasTransactionalObjects())
return Collections.EMPTY_SET;
return _transCache.copy();
Modified:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jta/ContainerTest.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jta/ContainerTest.java?rev=824454&r1=824453&r2=824454&view=diff
==============================================================================
---
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jta/ContainerTest.java
(original)
+++
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jta/ContainerTest.java
Mon Oct 12 18:48:10 2009
@@ -25,7 +25,7 @@
/**
* Simulates a container transaction around a test method.
- *
+ * <br>
* The concrete tests derived from this class must adhere to the following
guidelines:
* <LI>They must configure openjpa.ManagedRuntime in setUp() properties as
* to <code>org.apache.openjpa.jta.JTAManagedRuntime</code>
Added:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/PostRemoveCallbackEntity.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/PostRemoveCallbackEntity.java?rev=824454&view=auto
==============================================================================
---
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/PostRemoveCallbackEntity.java
(added)
+++
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/PostRemoveCallbackEntity.java
Mon Oct 12 18:48:10 2009
@@ -0,0 +1,70 @@
+/*
+ * 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.event;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.PostRemove;
+
+/**
+ * An entity for testing PostRemove callback.
+ *
+ * @see TestPostRemove
+ *
+ * @author Pinaki Poddar
+ *
+ */
+...@entity
+public class PostRemoveCallbackEntity {
+ @Id
+ @GeneratedValue
+ private long id;
+
+ private String name;
+
+ transient long postRemoveTime;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ @PostRemove
+ public void postRemove() {
+ if (postRemoveTime != 0) {
+ throw new RuntimeException(".postRemove has been called more than
once");
+ }
+// if (id == 0) {
+// throw new RuntimeException(" must have an identity value
assigned on PostRemove callback");
+// }
+ postRemoveTime = System.nanoTime();
+ }
+
+ public long getPostRemoveTime() {
+ return postRemoveTime;
+ }
+}
Propchange:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/PostRemoveCallbackEntity.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestPostRemove.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestPostRemove.java?rev=824454&view=auto
==============================================================================
---
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestPostRemove.java
(added)
+++
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestPostRemove.java
Mon Oct 12 18:48:10 2009
@@ -0,0 +1,136 @@
+/*
+ * 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.event;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.jta.ContainerTest;
+
+/**
+ * Tests PostRemove callback within a pseudo-container environment.
+ *
+ * According to JPA 2.0 Specification Section 3.5.2 (edited for PostRemove
only and readability)
+ *
+ * "a) The PostRemove callback method is invoked for an entity after the
entity has been removed.
+ *
+ * b) This callback will also be invoked on all entities to which these
operations are cascaded.
+ *
+ * c) The PostRemove method will be invoked after the database delete
operation. The database operation
+ * may occur directly after the remove operation have been invoked or they
may occur directly after
+ * a flush operation has occurred (which may be at the end of the
transaction)."
+ * <br>
+ * The test runs within a test harness that emulates application managed
transaction semantics
+ * of a container.
+ *
+ * @author Pinaki Poddar
+ *
+ */
+public class TestPostRemove extends ContainerTest {
+ @Override
+ public void setUp() throws Exception {
+ super.setUp(PostRemoveCallbackEntity.class);
+ }
+
+ @Override
+ public String getPersistenceUnitName() {
+ return "post-remove";
+ }
+
+ public void testPostRemoveInvokedOnlyAfterDatabaseDeleteWithLogicalFlush()
{
+ EntityManager em = emf.createEntityManager();
+ em.joinTransaction();
+ PostRemoveCallbackEntity pc = new PostRemoveCallbackEntity();
+ em.persist(pc);
+ em.flush();
+ em.remove(pc);
+ commit();
+ assertTrue("PostRemove not called after commit",
isPostRemovedInvoked(pc)
+ && pc.getPostRemoveTime() <= System.nanoTime());
+ }
+
+ public void testPostRemoveInvokedAfterDatabaseDeleteWithoutFlush() {
+ EntityManager em = emf.createEntityManager();
+ em.joinTransaction();
+ PostRemoveCallbackEntity pc = new PostRemoveCallbackEntity();
+ em.persist(pc);
+ em.remove(pc);
+ assertFalse("PostRemove called before commit",
isPostRemovedInvoked(pc));
+ commit();
+ assertTrue("PostRemove not called after commit",
pc.getPostRemoveTime() <= System.nanoTime());
+ }
+
+ public void testPostRemoveNotInvokedAfterRollback() {
+ EntityManager em = emf.createEntityManager();
+ em.joinTransaction();
+ PostRemoveCallbackEntity pc = new PostRemoveCallbackEntity();
+ em.persist(pc);
+ em.remove(pc);
+ assertFalse("PostRemove called before rollback",
isPostRemovedInvoked(pc));
+ rollback();
+ assertTrue("PostRemove called after rollback", pc.getPostRemoveTime()
<= System.nanoTime());
+ }
+
+ public void testPostRemoveNotInvokedAfterRollbackWithIntermediateFlush() {
+ EntityManager em = emf.createEntityManager();
+ em.joinTransaction();
+ PostRemoveCallbackEntity pc = new PostRemoveCallbackEntity();
+ em.persist(pc);
+ em.flush();
+ assertFalse("PostRemove called after flush", isPostRemovedInvoked(pc));
+ em.remove(pc);
+ assertFalse("PostRemove called before rollback",
isPostRemovedInvoked(pc));
+ rollback();
+ assertTrue("PostRemove called after rollback", pc.getPostRemoveTime()
<= System.nanoTime());
+ }
+
+ public void testPostRemoveInvokedOnFlushThatIssuesDatabaseDelete() {
+ EntityManager em = emf.createEntityManager();
+ em.joinTransaction();
+ PostRemoveCallbackEntity pc = new PostRemoveCallbackEntity();
+ em.persist(pc);
+ commit();
+ em.close();
+
+ em = emf.createEntityManager();
+ em.joinTransaction();
+ pc = em.find(PostRemoveCallbackEntity.class, pc.getId());
+ assertNotNull(pc);
+ em.remove(pc);
+ assertFalse("PostRemove called after logical remove",
isPostRemovedInvoked(pc));
+ em.flush();
+ assertTrue("PostRemove not called after delete flush",
isPostRemovedInvoked(pc));
+ commit();
+ assertTrue("PostRemove not called after commit",
pc.getPostRemoveTime() <= System.nanoTime());
+ }
+
+
+ public void testPostRemoveNotInvokedAfterDatabaseInsert() {
+ EntityManager em = emf.createEntityManager();
+ em.joinTransaction();
+ PostRemoveCallbackEntity pc = new PostRemoveCallbackEntity();
+ em.persist(pc);
+ assertFalse("PostRemove called before commit",
isPostRemovedInvoked(pc));
+ commit();
+ assertFalse("PostRemove called after commit",
isPostRemovedInvoked(pc));
+ }
+
+ boolean isPostRemovedInvoked(PostRemoveCallbackEntity pc) {
+ return pc.getPostRemoveTime() != 0;
+ }
+}
Propchange:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestPostRemove.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/SingleEMFTestCase.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/SingleEMFTestCase.java?rev=824454&r1=824453&r2=824454&view=diff
==============================================================================
---
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/SingleEMFTestCase.java
(original)
+++
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/SingleEMFTestCase.java
Mon Oct 12 18:48:10 2009
@@ -51,6 +51,7 @@
* subclass.
*/
public void setUp() throws Exception {
+ super.setUp();
setUp(new Object[0]);
}
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=824454&r1=824453&r2=824454&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
Mon Oct 12 18:48:10 2009
@@ -242,6 +242,14 @@
value="buildSchema(SchemaAction='drop,add')"/>
</properties>
</persistence-unit>
+
+ <persistence-unit name="post-remove" transaction-type="JTA">
+
<class>org.apache.openjpa.persistence.event.PostRemoveCallbackEntity</class>
+ <properties>
+ <property name="openjpa.jdbc.SynchronizeMappings"
value="buildSchema(SchemaAction='drop,add')"/>
+ <property name="openjpa.ManagedRuntime"
value="org.apache.openjpa.jta.JTAManagedRuntime"/>
+ </properties>
+ </persistence-unit>
</persistence>