openjpa-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From p..@apache.org
Subject svn commit: r617525 - in /openjpa/trunk: openjpa-kernel/src/main/java/org/apache/openjpa/event/ openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ openjpa-kernel/src/main/java/org/apache/openjpa/util/ openjpa-kernel/src/main/resources/org/apache/o...
Date Fri, 01 Feb 2008 15:46:55 GMT
Author: pcl
Date: Fri Feb  1 07:46:51 2008
New Revision: 617525

URL: http://svn.apache.org/viewvc?rev=617525&view=rev
Log:
OPENJPA-506. svn merge -c 617334 ../branches/1.0.x; svn merge -c 617363 ../branches/1.0.x,
plus modifications for serialization.

Modified:
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/event/LifecycleEvent.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/event/LifecycleEventManager.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/VersionAttachStrategy.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/ImplHelper.java
    openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/event/localizer.properties
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/ExceptionsFromCallbacksEntity.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/TestExceptionsFromCallbacks.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/PersistenceTestCase.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/SingleEMFTestCase.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/MetaDataParsers.java

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/event/LifecycleEvent.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/event/LifecycleEvent.java?rev=617525&r1=617524&r2=617525&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/event/LifecycleEvent.java
(original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/event/LifecycleEvent.java
Fri Feb  1 07:46:51 2008
@@ -42,6 +42,12 @@
     public static final int AFTER_PERSIST = 1;
 
     /**
+     * Event type when an instance is made persistent, after the record has
+     * been written to the store
+     */
+    public static final int AFTER_PERSIST_PERFORMED = 18;
+
+    /**
      * Event type when an instance is loaded.
      */
     public static final int AFTER_LOAD = 2;
@@ -77,6 +83,12 @@
     public static final int AFTER_DELETE = 8;
 
     /**
+     * Event type when an instance is deleted, after the record has been
+     * deleted from the store.
+     */
+    public static final int AFTER_DELETE_PERFORMED = 19;
+
+    /**
      * Event type when an instance is dirtied for the first time.
      */
     public static final int BEFORE_DIRTY = 9;
@@ -122,11 +134,25 @@
     public static final int AFTER_REFRESH = 17;
 
     /**
+     * Event type when an instance is modified. This is not invoked for
+     * PNEW records, but is invoked for PNEWFLUSHED.
+     */
+    public static final int BEFORE_UPDATE = 20;
+
+    /**
+     * Event type when an instance is modified, after the change has been
+     * sent to the store. This is not invoked for PNEW records, but is
+     * invoked for PNEWFLUSHED records.
+     */
+    public static final int AFTER_UPDATE_PERFORMED = 21;
+
+    /**
      * Convenience array of all event types.
      */
     public static final int[] ALL_EVENTS = new int[]{
         BEFORE_PERSIST,
         AFTER_PERSIST,
+        AFTER_PERSIST_PERFORMED,
         AFTER_LOAD,
         BEFORE_STORE,
         AFTER_STORE,
@@ -134,6 +160,7 @@
         AFTER_CLEAR,
         BEFORE_DELETE,
         AFTER_DELETE,
+        AFTER_DELETE_PERFORMED,
         BEFORE_DIRTY,
         AFTER_DIRTY,
         BEFORE_DIRTY_FLUSHED,
@@ -143,6 +170,8 @@
         BEFORE_ATTACH,
         AFTER_ATTACH,
         AFTER_REFRESH,
+        BEFORE_UPDATE,
+        AFTER_UPDATE_PERFORMED,
     };
 
     private final int _type;

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/event/LifecycleEventManager.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/event/LifecycleEventManager.java?rev=617525&r1=617524&r2=617525&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/event/LifecycleEventManager.java
(original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/event/LifecycleEventManager.java
Fri Feb  1 07:46:51 2008
@@ -29,6 +29,9 @@
 
 import org.apache.openjpa.meta.ClassMetaData;
 import org.apache.openjpa.meta.MetaDataDefaults;
+import org.apache.openjpa.lib.log.Log;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.util.InvalidStateException;
 
 /**
  * Manager that can be used to track and notify listeners on lifecycle events.
@@ -49,6 +52,9 @@
 
     private static final Exception[] EMPTY_EXCEPTIONS = new Exception[0];
 
+    private static final Localizer _loc = Localizer.forPackage(
+        LifecycleEventManager.class);
+
     private Map _classListeners = null; // class -> listener list
     private ListenerList _listeners = null;
     private List _addListeners = new LinkedList();
@@ -133,7 +139,9 @@
      */
     public boolean hasPersistListeners(Object source, ClassMetaData meta) {
         return hasHandlers(source, meta, LifecycleEvent.BEFORE_PERSIST)
-            || hasHandlers(source, meta, LifecycleEvent.AFTER_PERSIST);
+            || hasHandlers(source, meta, LifecycleEvent.AFTER_PERSIST)
+            || hasHandlers(source, meta,
+                LifecycleEvent.AFTER_PERSIST_PERFORMED);
     }
 
     /**
@@ -141,7 +149,8 @@
      */
     public boolean hasDeleteListeners(Object source, ClassMetaData meta) {
         return hasHandlers(source, meta, LifecycleEvent.BEFORE_DELETE)
-            || hasHandlers(source, meta, LifecycleEvent.AFTER_DELETE);
+            || hasHandlers(source, meta, LifecycleEvent.AFTER_DELETE)
+            || hasHandlers(source, meta, LifecycleEvent.AFTER_DELETE_PERFORMED);
     }
 
     /**
@@ -170,6 +179,14 @@
     /**
      * Return whether there are listeners or callbacks for the given source.
      */
+    public boolean hasUpdateListeners(Object source, ClassMetaData meta) {
+        return hasHandlers(source, meta, LifecycleEvent.BEFORE_UPDATE)
+            || hasHandlers(source, meta, LifecycleEvent.AFTER_UPDATE_PERFORMED);
+    }
+
+    /**
+     * Return whether there are listeners or callbacks for the given source.
+     */
     public boolean hasDirtyListeners(Object source, ClassMetaData meta) {
         return hasHandlers(source, meta, LifecycleEvent.BEFORE_DIRTY)
             || hasHandlers(source, meta, LifecycleEvent.AFTER_DIRTY);
@@ -471,6 +488,10 @@
                                 ((AttachListener) listener).afterAttach(ev);
                         }
                         break;
+                    default:
+                        throw new InvalidStateException(
+                            _loc.get("unknown-lifecycle-event",
+                                Integer.toString(type)));
                 }
             }
             catch (Exception e) {

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java?rev=617525&r1=617524&r2=617525&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java
(original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java
Fri Feb  1 07:46:51 2008
@@ -969,6 +969,11 @@
 
         if (reason != BrokerImpl.FLUSH_ROLLBACK
             && reason != BrokerImpl.FLUSH_LOGICAL) {
+            // analyze previous state for later
+            boolean wasNew = isNew();
+            boolean wasFlushed = isFlushed();
+            boolean wasDeleted = isDeleted();
+
             // all dirty fields were flushed
             _flush.or(_dirty);
 
@@ -989,6 +994,15 @@
             // if this object was stored with preFlush, do post-store callback
             if ((_flags & FLAG_PRE_FLUSHED) > 0)
                 fireLifecycleEvent(LifecycleEvent.AFTER_STORE);
+
+            // do post-update as needed
+            if (wasNew && !wasFlushed)
+                fireLifecycleEvent(LifecycleEvent.AFTER_PERSIST_PERFORMED);
+            else if (wasDeleted)
+                fireLifecycleEvent(LifecycleEvent.AFTER_DELETE_PERFORMED);
+            else 
+                // updates and new-flushed with changes
+                fireLifecycleEvent(LifecycleEvent.AFTER_UPDATE_PERFORMED);
         } else if (reason == BrokerImpl.FLUSH_ROLLBACK) {
             // revert to last loaded version and original oid
             assignVersionField(_loadVersion);
@@ -2786,6 +2800,11 @@
 
         if (isPersistent()) {
             fireLifecycleEvent(LifecycleEvent.BEFORE_STORE);
+            // BEFORE_PERSIST is handled during Broker.persist and Broker.attach
+            if (isDeleted())
+                fireLifecycleEvent(LifecycleEvent.BEFORE_DELETE);
+            else if (!(isNew() && !isFlushed()))
+                fireLifecycleEvent(LifecycleEvent.BEFORE_UPDATE);
             _flags |= FLAG_PRE_FLUSHED;
         }
 

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/VersionAttachStrategy.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/VersionAttachStrategy.java?rev=617525&r1=617524&r2=617525&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/VersionAttachStrategy.java
(original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/VersionAttachStrategy.java
Fri Feb  1 07:46:51 2008
@@ -33,6 +33,7 @@
 import org.apache.openjpa.util.ObjectNotFoundException;
 import org.apache.openjpa.util.OptimisticException;
 import org.apache.openjpa.util.ImplHelper;
+import org.apache.openjpa.event.LifecycleEvent;
 
 /**
  * Handles attaching instances using version and primary key fields.
@@ -133,8 +134,13 @@
             return into;
         }
 
-        // invoke any preAttach on the detached instance
-        manager.fireBeforeAttach(toAttach, meta);
+        if (isNew) {
+            broker.fireLifecycleEvent(toAttach, null, meta,
+                LifecycleEvent.BEFORE_PERSIST);
+        } else {
+            // invoke any preAttach on the detached instance
+            manager.fireBeforeAttach(toAttach, meta);
+        }
 
         // assign the detached pc the same state manager as the object we're
         // copying into during the attach process

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/ImplHelper.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/ImplHelper.java?rev=617525&r1=617524&r2=617525&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/ImplHelper.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/ImplHelper.java Fri
Feb  1 07:46:51 2008
@@ -168,9 +168,9 @@
         }
     }
 
-    /** 
-     * Returns the fields of the state that require an update. 
-     *  
+    /**
+     * Returns the fields of the state that require an update.
+     *
      * @param  sm  the state to check
      * @return the BitSet of fields that need update, or null if none
      */

Modified: openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/event/localizer.properties
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/event/localizer.properties?rev=617525&r1=617524&r2=617525&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/event/localizer.properties
(original)
+++ openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/event/localizer.properties
Fri Feb  1 07:46:51 2008
@@ -96,4 +96,6 @@
 method-notfound: Method "{1}" with arguments of type: {2} \
     not found in class "{0}".
 broker-factory-listener-exception: Exception thrown while calling a \
-    BrokerFactoryListener. This exception will be ignored.
\ No newline at end of file
+    BrokerFactoryListener. This exception will be ignored.
+unknown-lifecycle-event: An unknown lifecycle event was encountered. Please \
+    report this to dev@openjpa.apache.org. Event type: {0}.
\ No newline at end of file

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/ExceptionsFromCallbacksEntity.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/ExceptionsFromCallbacksEntity.java?rev=617525&r1=617524&r2=617525&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/ExceptionsFromCallbacksEntity.java
(original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/ExceptionsFromCallbacksEntity.java
Fri Feb  1 07:46:51 2008
@@ -24,29 +24,54 @@
 import javax.persistence.PrePersist;
 import javax.persistence.PreUpdate;
 import javax.persistence.Version;
-
+import javax.persistence.PreRemove;
+import javax.persistence.PostRemove;
+import javax.persistence.PostUpdate;
+import javax.persistence.PostPersist;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Transient;
 
 @Entity
 public class ExceptionsFromCallbacksEntity {
-    @Id private long id;
+    @Id @GeneratedValue private long id;
     @Version private int version;
-    private boolean throwOnPrePersist;
-    private boolean throwOnPreUpdate;
+    @Transient private boolean throwOnPrePersist;
+    @Transient private boolean throwOnPostPersist;
+    @Transient private boolean throwOnPreUpdate;
+    @Transient private boolean throwOnPostUpdate;
     private boolean throwOnPostLoad;
+    @Transient private boolean throwOnPreRemove;
+    @Transient private boolean throwOnPostRemove;
     private String stringField;
-    
+
     public void setThrowOnPrePersist(boolean b) {
         throwOnPrePersist = b;
     }
 
-    public void setThrowOnPostLoad(boolean b) {
-        throwOnPostLoad = b;
+    public void setThrowOnPostPersist(boolean b) {
+        throwOnPostPersist = b;
     }
 
     public void setThrowOnPreUpdate(boolean b) {
         throwOnPreUpdate = b;
     }
 
+    public void setThrowOnPostUpdate(boolean b) {
+        throwOnPostUpdate = b;
+    }
+
+    public void setThrowOnPostLoad(boolean b) {
+        throwOnPostLoad = b;
+    }
+
+    public void setThrowOnPreRemove(boolean b) {
+        throwOnPreRemove = b;
+    }
+
+    public void setThrowOnPostRemove(boolean b) {
+        throwOnPostRemove = b;
+    }
+
     public void setStringField(String s) {
         stringField = s;
     }
@@ -57,18 +82,50 @@
             throw new CallbackTestException();
     }
 
+    @PostPersist
+    public void postPersist() {
+        if (throwOnPostPersist)
+            throw new CallbackTestException();
+    }
+
+    @PostLoad
+    public void postLoad() {
+        if (throwOnPostLoad && isInvokedFromTestMethod())
+            throw new CallbackTestException();
+    }
+
+    private boolean isInvokedFromTestMethod() {
+        return TestExceptionsFromCallbacks.testRunning;
+    }
+
     @PreUpdate
     public void preUpdate() {
         if (throwOnPreUpdate)
             throw new CallbackTestException();
     }
 
-    @PostLoad
-    public void postLoad() {
-        if (throwOnPostLoad)
+    @PostUpdate
+    public void postUpdate() {
+        if (throwOnPostUpdate)
             throw new CallbackTestException();
     }
-    
+
+    @PreRemove
+    public void preRemove() {
+        if (throwOnPreRemove && isInvokedFromTestMethod())
+            throw new CallbackTestException();
+    }
+
+    @PostRemove
+    public void postRemove() {
+        if (throwOnPostRemove && isInvokedFromTestMethod())
+            throw new CallbackTestException();
+    }
+
+    public Object getId() {
+        return id;
+    }
+
     public class CallbackTestException
         extends RuntimeException {
     }

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/TestExceptionsFromCallbacks.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/TestExceptionsFromCallbacks.java?rev=617525&r1=617524&r2=617525&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/TestExceptionsFromCallbacks.java
(original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/TestExceptionsFromCallbacks.java
Fri Feb  1 07:46:51 2008
@@ -18,18 +18,15 @@
  */
 package org.apache.openjpa.persistence.callbacks;
 
-import java.util.HashMap;
-import java.util.Map;
-
+import java.util.Set;
+import java.util.HashSet;
 import javax.persistence.EntityManager;
-import javax.persistence.Persistence;
 import javax.persistence.RollbackException;
 
-import junit.framework.TestCase;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
 import org.apache.openjpa.persistence.OpenJPAPersistence;
 import org.apache.openjpa.persistence.callbacks.ExceptionsFromCallbacksEntity.CallbackTestException;
 import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+import org.apache.openjpa.enhance.PersistenceCapable;
 
 /**
  * Tests against JPA section 3.5's description of callback exception handling.
@@ -37,8 +34,35 @@
 public class TestExceptionsFromCallbacks
     extends SingleEMFTestCase {
 
+    public static boolean testRunning = false;
+
+    @Override
     public void setUp() {
-        setUp(ExceptionsFromCallbacksEntity.class);
+        Set needEnhancement = new HashSet();
+        needEnhancement.add(
+            "testPostUpdateExceptionDuringFlushWithNewInstance");
+        needEnhancement.add(
+            "testPreUpdateExceptionDuringFlushWithExistingFlushedInstance");
+        needEnhancement.add(
+            "testPreUpdateExceptionDuringCommitWithExistingFlushedInstance");
+        needEnhancement.add(
+            "testPostUpdateExceptionDuringFlushWithExistingFlushedInstance");
+        needEnhancement.add(
+            "testPostUpdateExceptionDuringCommitWithExistingFlushedInstance");
+        if (!PersistenceCapable.class.isAssignableFrom(
+            ExceptionsFromCallbacksEntity.class)
+            && needEnhancement.contains(getName()))
+            // actually, we really only need redef
+            fail("this test method does not work without enhancement");
+
+        setUp(ExceptionsFromCallbacksEntity.class, CLEAR_TABLES, "openjpa.Log", "SQL=TRACE");
+        testRunning = true;
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        testRunning = false;
+        super.tearDown();
     }
 
     public void testPrePersistException() {
@@ -60,13 +84,41 @@
         }
     }
 
-    public void testPreUpdateExceptionDuringFlush() {
+    public void testPrePersistExceptionOnMerge() {
         EntityManager em = emf.createEntityManager();
         em.getTransaction().begin();
         ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
-        o.setThrowOnPreUpdate(true);
+        o.setThrowOnPrePersist(true);
+        try {
+            em.merge(o);
+            fail("merge should have failed");
+        } catch (CallbackTestException cte) {
+            // transaction should be still active, but marked for rollback
+            assertTrue(em.getTransaction().isActive());
+            assertTrue(em.getTransaction().getRollbackOnly());
+        } finally {
+            if (em.getTransaction().isActive())
+                em.getTransaction().rollback();
+            em.close();
+        }
+    }
+
+    public void testPostPersistExceptionDuringFlush() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
+        o.setThrowOnPostPersist(true);
         em.persist(o);
+        mutateAndFlush(em, o);
+    }
+
+    private void mutateAndFlush(EntityManager em,
+        ExceptionsFromCallbacksEntity o) {
         o.setStringField("foo");
+        flush(em);
+    }
+
+    private void flush(EntityManager em) {
         try {
             em.flush();
             fail("flush should have failed");
@@ -81,20 +133,29 @@
         }
     }
 
-    public void testPreUpdateExceptionDuringCommit() {
+    public void testPostPersistExceptionDuringCommit() {
         EntityManager em = emf.createEntityManager();
         em.getTransaction().begin();
         ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
-        o.setThrowOnPreUpdate(true);
+        o.setThrowOnPostPersist(true);
         em.persist(o);
+        mutateAndCommit(em, o);
+    }
+
+    private void mutateAndCommit(EntityManager em,
+        ExceptionsFromCallbacksEntity o) {
         o.setStringField("foo");
+        commit(em);
+    }
+
+    private void commit(EntityManager em) {
         try {
             em.getTransaction().commit();
             fail("commit should have failed");
         } catch (RollbackException re) {
             assertEquals(CallbackTestException.class,
                 re.getCause().getClass());
-            
+
             // transaction should be rolled back at this point
             assertFalse(em.getTransaction().isActive());
         } finally {
@@ -103,7 +164,253 @@
             em.close();
         }
     }
-    
+
+    public void testPrePersistExceptionDuringFlushWithNewFlushedInstance() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
+        em.persist(o);
+        em.flush();
+        o.setThrowOnPrePersist(true);
+        // should pass; pre-persist should not be triggered
+        o.setStringField("foo");
+        em.flush();
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void testPrePersistExceptionDuringCommitWithNewFlushedInstance() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
+        em.persist(o);
+        em.flush();
+        o.setThrowOnPrePersist(true);
+        // should pass; pre-persist should not be triggered
+        o.setStringField("foo");
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void testPostPersistExceptionDuringFlushWithNewFlushedInstance() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
+        em.persist(o);
+        em.flush();
+        o.setThrowOnPostPersist(true);
+        // should pass; post-persist should not be triggered
+        o.setStringField("foo");
+        em.flush();
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void testPostPersistExceptionDuringCommitWithNewFlushedInstance() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
+        em.persist(o);
+        em.flush();
+        o.setThrowOnPostPersist(true);
+        // should pass; post-persist should not be triggered
+        o.setStringField("foo");
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void testPreUpdateExceptionWithNewInstance() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
+        o.setThrowOnPreUpdate(true);
+        em.persist(o);
+        o.setStringField("foo");
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void testPostUpdateExceptionDuringFlushWithNewInstance() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
+        o.setThrowOnPostUpdate(true);
+        em.persist(o);
+        o.setStringField("foo");
+        em.flush();
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void testPostUpdateExceptionDuringCommitWithNewInstance() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
+        o.setThrowOnPostUpdate(true);
+        em.persist(o);
+        o.setStringField("foo");
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void testPreUpdateExceptionDuringFlushWithNewFlushedInstance() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
+        em.persist(o);
+        em.flush();
+        o.setThrowOnPreUpdate(true);
+        mutateAndFlush(em, o);
+    }
+
+    public void testPreUpdateExceptionDuringCommitWithNewFlushedInstance() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
+        em.persist(o);
+        em.flush();
+        o.setThrowOnPreUpdate(true);
+        mutateAndCommit(em, o);
+    }
+
+    public void testPostUpdateExceptionDuringFlushWithNewFlushedInstance() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
+        em.persist(o);
+        em.flush();
+        o.setThrowOnPostUpdate(true);
+        mutateAndFlush(em, o);
+    }
+
+    public void testPostUpdateExceptionDuringCommitWithNewFlushedInstance() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
+        em.persist(o);
+        em.flush();
+        o.setThrowOnPostUpdate(true);
+        mutateAndCommit(em, o);
+    }
+
+    public void testPreUpdateExceptionDuringFlushWithExistingInstance() {
+        Object oid = insert("new instance");
+
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        ExceptionsFromCallbacksEntity o =
+            em.find(ExceptionsFromCallbacksEntity.class, oid);
+        o.setThrowOnPreUpdate(true);
+        mutateAndFlush(em, o);
+    }
+
+    private Object insert(String s) {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
+        o.setStringField(s);
+        em.persist(o);
+        em.getTransaction().commit();
+        em.close();
+        return o.getId();
+    }
+
+    public void testPreUpdateExceptionDuringCommitWithExistingInstance() {
+        Object oid = insert("new instance");
+
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        ExceptionsFromCallbacksEntity o =
+            em.find(ExceptionsFromCallbacksEntity.class, oid);
+        o.setThrowOnPreUpdate(true);
+        mutateAndCommit(em, o);
+    }
+
+    public void testPostUpdateExceptionDuringFlushWithExistingInstance() {
+        Object oid = insert("new instance");
+
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        ExceptionsFromCallbacksEntity o =
+            em.find(ExceptionsFromCallbacksEntity.class, oid);
+        o.setThrowOnPostUpdate(true);
+        mutateAndFlush(em, o);
+    }
+
+    public void testPostUpdateExceptionDuringCommitWithExistingInstance() {
+        Object oid = insert("new instance");
+
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        ExceptionsFromCallbacksEntity o =
+            em.find(ExceptionsFromCallbacksEntity.class, oid);
+        o.setThrowOnPostUpdate(true);
+        mutateAndCommit(em, o);
+    }
+
+    public void testPreUpdateExceptionDuringFlushWithExistingFlushedInstance() {
+        Object oid = insert("new instance");
+
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        ExceptionsFromCallbacksEntity o =
+            em.find(ExceptionsFromCallbacksEntity.class, oid);
+        o.setStringField("foo");
+        em.flush();
+        o.setThrowOnPreUpdate(true);
+        // there's no additional flush work; should not re-invoke the callback
+        em.flush();
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void testPreUpdateExceptionDuringCommitWithExistingFlushedInstance(){
+        Object oid = insert("new instance");
+
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        ExceptionsFromCallbacksEntity o =
+            em.find(ExceptionsFromCallbacksEntity.class, oid);
+        o.setStringField("foo");
+        em.flush();
+        o.setThrowOnPreUpdate(true);
+        // there's no additional flush work; should not re-invoke the callback
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void testPostUpdateExceptionDuringFlushWithExistingFlushedInstance(){
+        Object oid = insert("new instance");
+
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        ExceptionsFromCallbacksEntity o =
+            em.find(ExceptionsFromCallbacksEntity.class, oid);
+        o.setStringField("foo");
+        em.flush();
+        o.setThrowOnPostUpdate(true);
+        // no mutations; should not trigger a PostUpdate
+        em.flush();
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void testPostUpdateExceptionDuringCommitWithExistingFlushedInstance()
+    {
+        Object oid = insert("new instance");
+
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        ExceptionsFromCallbacksEntity o =
+            em.find(ExceptionsFromCallbacksEntity.class, oid);
+        o.setStringField("foo");
+        em.flush();
+        // no mutations; should not trigger a PostUpdate
+        o.setThrowOnPostUpdate(true);
+        em.getTransaction().commit();
+        em.close();
+    }
+
     public void testPostLoadException() {
         EntityManager em = emf.createEntityManager();
         em.getTransaction().begin();
@@ -117,7 +424,7 @@
         em = emf.createEntityManager();
         em.getTransaction().begin();
         try {
-            o = em.find(ExceptionsFromCallbacksEntity.class, oid);
+            em.find(ExceptionsFromCallbacksEntity.class, oid);
             fail("find should have failed");
         } catch (CallbackTestException cte) {
             // transaction should be active but marked for rollback
@@ -128,5 +435,108 @@
                 em.getTransaction().rollback();
             em.close();
         }
+    }
+
+    public void testPreDeleteException() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
+        em.persist(o);
+        em.flush();
+        o.setThrowOnPreRemove(true);
+        try {
+            em.remove(o);
+        } catch (CallbackTestException cte) {
+            // transaction should be active but marked for rollback
+            assertTrue(em.getTransaction().isActive());
+            assertTrue(em.getTransaction().getRollbackOnly());
+        } finally {
+            if (em.getTransaction().isActive())
+                em.getTransaction().rollback();
+            em.close();
+        }
+    }
+
+    public void testPostDeleteExceptionDuringFlush() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
+        em.persist(o);
+        em.flush();
+        o.setThrowOnPostRemove(true);
+        try {
+            em.remove(o);
+        } catch (CallbackTestException e) {
+            em.getTransaction().rollback();
+            em.close();
+            fail("PostRemove is being called too soon (before SQL is issued)");
+        }
+        flush(em);
+    }
+
+    public void testPostDeleteExceptionDuringCommit() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
+        em.persist(o);
+        em.flush();
+        o.setThrowOnPostRemove(true);
+        try {
+            em.remove(o);
+        } catch (CallbackTestException e) {
+            em.getTransaction().rollback();
+            em.close();
+            fail("PostRemove is being called too soon (before SQL is issued)");
+        }
+        commit(em);
+    }
+
+    public void testPreDeleteExceptionDoubleDelete() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
+        em.persist(o);
+        em.flush();
+        // this should pass
+        em.remove(o);
+        em.flush();
+        o.setThrowOnPreRemove(true);
+        // this shoud also pass; no work to do for delete
+        em.remove(o);
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void testPostDeleteExceptionDuringFlushDoubleDelete() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
+        em.persist(o);
+        em.flush();
+        // this should pass
+        em.remove(o);
+        em.flush();
+        o.setThrowOnPostRemove(true);
+        // this shoud also pass; no work to do for delete
+        em.remove(o);
+        em.flush();
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    public void testPostDeleteExceptionDuringCommitDoubleDelete() {
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        ExceptionsFromCallbacksEntity o = new ExceptionsFromCallbacksEntity();
+        em.persist(o);
+        em.flush();
+        // this should pass
+        em.remove(o);
+        em.flush();
+        o.setThrowOnPostRemove(true);
+        // this shoud also pass; no work to do for delete
+        em.remove(o);
+        em.getTransaction().commit();
+        em.close();
     }
 }

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/PersistenceTestCase.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/PersistenceTestCase.java?rev=617525&r1=617524&r2=617525&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/PersistenceTestCase.java
(original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/PersistenceTestCase.java
Fri Feb  1 07:46:51 2008
@@ -51,7 +51,7 @@
     /**
      * The {@link TestResult} instance for the current test run.
      */
-    private TestResult testResult;
+    protected TestResult testResult;
 
     /**
      * Create an entity manager factory. Put {@link #CLEAR_TABLES} in

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=617525&r1=617524&r2=617525&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
Fri Feb  1 07:46:51 2008
@@ -58,6 +58,11 @@
 
         try {
             clear(emf);
+        } catch (Exception e) {
+            // if a test failed, swallow any exceptions that happen
+            // during tear-down, as these just mask the original problem.
+            if (testResult.wasSuccessful())
+                throw e;
         } finally {
             closeEMF(emf);
         }

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/MetaDataParsers.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/MetaDataParsers.java?rev=617525&r1=617524&r2=617525&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/MetaDataParsers.java
(original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/MetaDataParsers.java
Fri Feb  1 07:46:51 2008
@@ -47,15 +47,15 @@
             case PRE_PERSIST:
                 return new int[]{ LifecycleEvent.BEFORE_PERSIST };
             case POST_PERSIST:
-                return new int[]{ LifecycleEvent.AFTER_PERSIST };
+                return new int[]{ LifecycleEvent.AFTER_PERSIST_PERFORMED };
             case PRE_REMOVE:
                 return new int[]{ LifecycleEvent.BEFORE_DELETE };
             case POST_REMOVE:
-                return new int[]{ LifecycleEvent.AFTER_DELETE };
+                return new int[]{ LifecycleEvent.AFTER_DELETE_PERFORMED };
             case PRE_UPDATE:
-                return new int[]{ LifecycleEvent.BEFORE_STORE };
+                return new int[]{ LifecycleEvent.BEFORE_UPDATE };
             case POST_UPDATE:
-                return new int[]{ LifecycleEvent.AFTER_STORE };
+                return new int[]{ LifecycleEvent.AFTER_UPDATE_PERFORMED };
             case POST_LOAD:
                 return new int[]{ LifecycleEvent.AFTER_LOAD,
                     LifecycleEvent.AFTER_REFRESH };



Mime
View raw message