You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by dw...@apache.org on 2009/09/21 22:01:44 UTC

svn commit: r817389 - in /openjpa/trunk: openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/TestMessageListener.java openjpa-project/src/doc/manual/migration_considerations.xml

Author: dwoods
Date: Mon Sep 21 20:01:44 2009
New Revision: 817389

URL: http://svn.apache.org/viewvc?rev=817389&view=rev
Log:
OPENJPA-1182 Backwards compatibility issues - PreUpdate and PostUpdate behavior.  Patch contributed by Tim McConnell with some minor package name and version checking changes.  Doc updates by Donald Woods.

Added:
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/TestMessageListener.java   (with props)
Modified:
    openjpa/trunk/openjpa-project/src/doc/manual/migration_considerations.xml

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/TestMessageListener.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/TestMessageListener.java?rev=817389&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/TestMessageListener.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/TestMessageListener.java Mon Sep 21 20:01:44 2009
@@ -0,0 +1,239 @@
+/*
+ * 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 agEmployee_Last_Name 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.compat;
+
+import javax.persistence.Query;
+
+import org.apache.openjpa.persistence.callbacks.Message;
+import org.apache.openjpa.persistence.callbacks.MessageListenerImpl;
+import org.apache.openjpa.conf.OpenJPAVersion;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+/**
+ * <b>TestCompatibile</b> is used to test various backwards compatibility scenarios between JPA 2.0 and JPA 1.2
+ * 
+ * <p>The following scenarios are tested:
+ * <ol>
+ * <li>preUpdate and postUpdate behavior in JPA 2.0 is different than in 1.2
+ * <li>TBD
+ * </ol>
+ * <p> 
+ * <b>Note(s):</b>
+ * <ul>
+ * <li>The proper openjpa.Compatibility value(s) must be provided in order for the testcases to succeed
+ * </ul>
+ */
+public class TestMessageListener extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp(Message.class, 
+              "openjpa.Compatibility", "default",
+              DROP_TABLES);
+    }
+
+    public void testUpdateInPreUpdate() {
+        // Create a new EntityManager from the EntityManagerFactory. The
+        // EntityManager is the main object in the persistence API, and is
+        // used to create, delete, and query objects, as well as access
+        // the current transaction
+        OpenJPAEntityManager em = emf.createEntityManager();
+        try {
+            // Begin a new local transaction so that we can persist a new entity
+            em.getTransaction().begin();
+
+            MessageListenerImpl.resetCounters();
+
+            // Create and persist a new Message entity
+            Message message = new Message("Hello Persistence!");
+            assertNull("Test message's created field to be null.", message.getCreated());
+            assertNull("Test message's updated field to be null.", message.getUpdated());
+
+            em.persist(message);
+
+            // Pre-persist invoked, created and updated fields set
+            assertStatus(1, 0, 0, 0, 0, 0, 0);
+            assertNotNull("Test message's created field being set.", message.getCreated());
+            assertNotNull("Test message's updated field being set.", message.getUpdated());
+
+            // Perform a simple query to get the Message
+            Query q = em.createQuery("select m from Message m where m.id=" + message.getId());
+            Message m = (Message) q.getSingleResult();
+            assertEquals("Test first expected message.", "Hello Persistence!",m.getMessage());
+            assertNotNull("Test message's created field being set.", m.getCreated());
+            assertNotNull("Test message's updated field being set.", m.getUpdated());
+
+            // Query cause flush to occur, hence fire the postPersist event
+            assertStatus(1, 1, 0, 0, 0, 0, 0);
+
+            // Create and persist another new Message entity
+            message = new Message("Hello Persistence 2!");
+            assertNull("Test message's created field to be null.", message.getCreated());
+            assertNull("Test message's updated field to be null.", message.getUpdated());
+
+            em.persist(message);
+
+            // Pre-persist invoked, created and updated fields set
+            assertStatus(2, 1, 0, 0, 0, 0, 0);
+            assertNotNull("Test message's created field being set.", message.getCreated());
+            assertNotNull("Test message's updated field being set.", message.getUpdated());
+
+            em.getTransaction().commit();
+
+            // Complete the 2nd @postPersist
+            // preUpdate and postUpdate are called in 1.2.x but not in 1.3 or later
+            // See JPA2 Spec 3.5.2 Note about this being implementation dependent
+            if ((OpenJPAVersion.MAJOR_RELEASE >= 2) ||
+                ((OpenJPAVersion.MAJOR_RELEASE == 1) &&
+                 (OpenJPAVersion.MINOR_RELEASE >= 3))) {
+                assertStatus(2, 2, 0, 0, 0, 0, 0);
+            } else {
+                // prior to 2.0, pre/postUpdate was called
+                assertStatus(2, 2, 1, 1, 0, 0, 0);
+            }            
+
+            // Make an update to trigger the pre/postUpdater callbacks
+            em.getTransaction().begin();
+            message = em.find(Message.class,message.getId());
+            message.setMessage("Update field and trigger pre/postUpdate");
+            em.getTransaction().commit();
+
+            // Complete the 2nd @postPersist
+            if ((OpenJPAVersion.MAJOR_RELEASE >= 2) ||
+                ((OpenJPAVersion.MAJOR_RELEASE == 1) &&
+                    (OpenJPAVersion.MINOR_RELEASE >= 3))) {
+                assertStatus(2, 2, 1, 1, 0, 0, 0);
+            } else {
+                assertStatus(2, 2, 2, 2, 0, 0, 0);
+            }            
+        }
+        finally {
+            if (em != null && em.getTransaction().isActive())
+                em.getTransaction().rollback();
+            if (em != null && em.isOpen())
+                em.close();
+        }
+    } 
+
+    public void testUpdateInPreUpdate2() {
+        // Create a new EntityManager from the EntityManagerFactory. The
+        // EntityManager is the main object in the persistence API, and is
+        // used to create, delete, and query objects, as well as access
+        // the current transaction
+        OpenJPAEntityManager em = emf.createEntityManager();
+        try {
+            // Begin a new local transaction so that we can persist a new entity
+            em.getTransaction().begin();
+
+            MessageListenerImpl.resetCounters();
+
+            // Create and persist a new Message entity
+            Message message = new Message("Hello Persistence!");
+            assertNull("Test message's created field to be null.", message.getCreated());
+            assertNull("Test message's updated field to be null.", message.getUpdated());
+
+            em.persist(message);
+
+            // Pre-persist invoked, created and updated fields set
+            assertStatus(1, 0, 0, 0, 0, 0, 0);
+            assertNotNull("Test message's created field being set.", message.getCreated());
+            assertNotNull("Test message's updated field being set.", message.getUpdated());
+
+            // Perform a simple query to get the Message
+            Query q = em.createQuery("select m from Message m where m.id=" + message.getId());
+            Message m = (Message) q.getSingleResult();
+            assertEquals("Test first expected message.", "Hello Persistence!",m.getMessage());
+            assertNotNull("Test message's created field being set.", m.getCreated());
+            assertNotNull("Test message's updated field being set.", m.getUpdated());
+
+            // Query cause flush to occur, hence fire the postPersist event
+            assertStatus(1, 1, 0, 0, 0, 0, 0);
+
+            // Create and persist another new Message entity
+            message = new Message("Hello Persistence 2!");
+            assertNull("Test message's created field to be null.", message.getCreated());
+            assertNull("Test message's updated field to be null.", message.getUpdated());
+
+            em.persist(message);
+
+            // Pre-persist invoked, created and updated fields set
+            assertStatus(2, 1, 0, 0, 0, 0, 0);
+            assertNotNull("Test message's created field being set.", message.getCreated());
+            assertNotNull("Test message's updated field being set.", message.getUpdated());
+
+            // Update the entity before committing
+            message.setMessage("Combined Create and Update triggers");
+            // preUpdate and postUpdate are called in 1.2.x but not in 1.3 or later
+            // See JPA2 Spec 3.5.2 Note about this being implementation dependent
+            if ((OpenJPAVersion.MAJOR_RELEASE >= 2) ||
+                ((OpenJPAVersion.MAJOR_RELEASE == 1) &&
+                 (OpenJPAVersion.MINOR_RELEASE >= 3))) {
+                assertStatus(2, 1, 0, 0, 0, 0, 0);
+            } else {
+                // prior to 2.0, pre/postUpdate was called
+                assertStatus(2, 1, 1, 1, 0, 0, 0);
+            }            
+
+            em.getTransaction().commit();
+
+            // Complete the 2nd @postPersist
+            // preUpdate and postUpdate are called in 1.2.x but not in 1.3 or later
+            if ((OpenJPAVersion.MAJOR_RELEASE >= 2) ||
+                ((OpenJPAVersion.MAJOR_RELEASE == 1) &&
+                 (OpenJPAVersion.MINOR_RELEASE >= 3))) {
+                assertStatus(2, 2, 0, 0, 0, 0, 0);
+            } else {
+                assertStatus(2, 2, 1, 1, 0, 0, 0);
+            }            
+
+            // Make an update to trigger the pre/postUpdater callbacks
+            em.getTransaction().begin();
+            message = em.find(Message.class,message.getId());
+            message.setMessage("Update field and trigger pre/postUpdate");
+            em.getTransaction().commit();
+
+            // Complete the 2nd @postPersist
+            if ((OpenJPAVersion.MAJOR_RELEASE >= 2) ||
+                ((OpenJPAVersion.MAJOR_RELEASE == 1) &&
+                 (OpenJPAVersion.MINOR_RELEASE >= 3))) {
+                assertStatus(2, 2, 1, 1, 0, 0, 0);
+            } else {
+                assertStatus(2, 2, 2, 2, 0, 0, 0);
+            }            
+        }
+        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", prePersist, MessageListenerImpl.prePersistCount);
+        assertEquals("postPersist", postPersist, MessageListenerImpl.postPersistCount);
+        assertEquals("preUpdate", preUpdate, MessageListenerImpl.preUpdateCount);
+        assertEquals("postUpdate", postUpdate, MessageListenerImpl.postUpdateCount);
+        assertEquals("preRemove", preRemove, MessageListenerImpl.preRemoveCount);
+        assertEquals("postRemove", postRemove, MessageListenerImpl.postRemoveCount);
+        assertEquals("postLoad", postLoad, MessageListenerImpl.postLoadCount);
+    }
+}
+

Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/TestMessageListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: openjpa/trunk/openjpa-project/src/doc/manual/migration_considerations.xml
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-project/src/doc/manual/migration_considerations.xml?rev=817389&r1=817388&r2=817389&view=diff
==============================================================================
--- openjpa/trunk/openjpa-project/src/doc/manual/migration_considerations.xml (original)
+++ openjpa/trunk/openjpa-project/src/doc/manual/migration_considerations.xml Mon Sep 21 20:01:44 2009
@@ -203,8 +203,10 @@
     		<para>
     		The following sections indicate internal changes between
     		OpenJPA 1.x.x releases and the 2.0 release. As these are
-                internal implementation classes, no changes to applications
-                should be required.
+                internal implementation specific behaviors not covered by
+                the JPA specification, no changes should be required for
+                applications that did not use or depend upon OpenJPA specific
+                APIs or behavior.
     		</para>
     		<section id="getStrategy">
     			<title>
@@ -221,6 +223,31 @@
 				example test case demonstrating the change.
 			</para>
 		</section>
+    		<section id="prePostUpdate">
+    			<title>
+    				PreUpdate/PostUpdate Life Cycle Callbacks
+    			</title>
+    			<para>
+    				If an entity was updated between the persist()
+                                and commit() operations in OpenJPA 1.x, then 
+                                any PreUpdate and PostUpdate life cycle callback
+                                methods would be executed.  Starting in OpenJPA
+                                1.3 and 2.0, these callbacks will not get 
+                                executed.
+			</para>
+			<para>
+                                The JPA 2.0 specification section on "Semantics
+                                of the Life Cycle Callback Methods for Entities"
+                                has been updated to include a Note that the
+                                callback behavior for updating an entity after
+                                the persist operation is implementation specific
+                                and should not be relied upon.
+			</para>
+			<para>
+                                See OPENJPA-1182 for an
+				example test case demonstrating the change.
+			</para>
+		</section>
         </section>
     </section>
 </appendix>