Author: allee8285
Date: Fri Feb 18 16:59:16 2011
New Revision: 1072061

URL: http://svn.apache.org/viewvc?rev=1072061&view=rev
Log:
OPENJPA-1943 - Apply query timeout value to pessimistic row lock statement 
execution.

Modified:
    
openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/sql/sql-error-state-codes.xml
    
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
    
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java
    
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java
    
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/AbstractPersistenceTestCase.java
    
openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/SequencedActionsTest.java
    
openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/TestMixedLockManagerDeadlock.java
    
openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/TestPessimisticLocks.java
    
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java
    
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/QueryImpl.java

Modified: 
openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/sql/sql-error-state-codes.xml
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/sql/sql-error-state-codes.xml?rev=1072061&r1=1072060&r2=1072061&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/sql/sql-error-state-codes.xml
 (original)
+++ 
openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/sql/sql-error-state-codes.xml
 Fri Feb 18 16:59:16 2011
@@ -47,7 +47,7 @@
        </dictionary>
        
        <dictionary class="org.apache.openjpa.jdbc.sql.SQLServerDictionary">
-               <lock>1204,1205,1222,HY008</lock>
+               <lock>1204,1205,1222,HY008,40001</lock>
                
<referential-integrity>544,2601,2627,8114,8115</referential-integrity>
                <object-exists>23000</object-exists>
                <object-not-found></object-not-found>

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=1072061&r1=1072060&r2=1072061&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
 Fri Feb 18 16:59:16 2011
@@ -455,10 +455,14 @@ public class BrokerImpl
     }
 
     public FetchConfiguration pushFetchConfiguration() {
+               return pushFetchConfiguration(null);
+    }
+
+    public FetchConfiguration pushFetchConfiguration(FetchConfiguration fc) {
         if (_fcs == null)
             _fcs = new LinkedList<FetchConfiguration>();
         _fcs.add(_fc);
-        _fc = (FetchConfiguration) _fc.clone();
+        _fc = (FetchConfiguration) (fc != null ? fc : _fc).clone();
         return _fc;
     }
 

Modified: 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java?rev=1072061&r1=1072060&r2=1072061&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java
 (original)
+++ 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java
 Fri Feb 18 16:59:16 2011
@@ -154,6 +154,14 @@ public class DelegatingBroker
         }
     }
 
+    public FetchConfiguration pushFetchConfiguration(FetchConfiguration fc) {
+        try {
+            return _broker.pushFetchConfiguration(fc);
+        } catch (RuntimeException re) {
+            throw translate(re);
+        }
+    }
+
     public void popFetchConfiguration() {
         try {
             _broker.popFetchConfiguration();

Modified: 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java?rev=1072061&r1=1072060&r2=1072061&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java
 (original)
+++ 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java
 Fri Feb 18 16:59:16 2011
@@ -74,6 +74,15 @@ public interface StoreContext {
     public FetchConfiguration pushFetchConfiguration();
 
     /**
+     * Pushes the fetch configuration argument onto a stack, and makes the new 
configuration
+     * the active one.
+     *
+     * @since 2.1.1
+     * @return the new fetch configuration
+     */
+    public FetchConfiguration pushFetchConfiguration(FetchConfiguration fc);
+
+    /**
      * Pops the fetch configuration from the top of the stack, making the
      * next one down the active one. This returns void to avoid confusion,
      * since fetch configurations tend to be used in method-chaining

Modified: 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/AbstractPersistenceTestCase.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/AbstractPersistenceTestCase.java?rev=1072061&r1=1072060&r2=1072061&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/AbstractPersistenceTestCase.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/AbstractPersistenceTestCase.java
 Fri Feb 18 16:59:16 2011
@@ -271,6 +271,12 @@ public abstract class AbstractPersistenc
         for (Broker b : ((AbstractBrokerFactory) 
JPAFacadeHelper.toBrokerFactory(emf)).getOpenBrokers()) {
             if (b != null && !b.isClosed()) {
                 EntityManager em = JPAFacadeHelper.toEntityManager(b);
+                if( em.getTransaction().isActive() ) {
+                       try {
+                                               em.getTransaction().rollback();
+                                       } catch (Exception e) {
+                                       }
+                }
                 closeEM(em);
             }
         }

Modified: 
openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/SequencedActionsTest.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/SequencedActionsTest.java?rev=1072061&r1=1072060&r2=1072061&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/SequencedActionsTest.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/SequencedActionsTest.java
 Fri Feb 18 16:59:16 2011
@@ -684,41 +684,93 @@ public abstract class SequencedActionsTe
                             }
                         }
                     }
-                    String testExClass = null;
-                    Throwable curThrowable = null;
                     int threadId = threadToRun;
                     if (args.length > 1) {
                         threadId = (Integer) args[1];
                     }
-                    TestThread exThread = threads.get(threadId);
-                    curThrowable = exThread.throwable;
-                    testExClass = processException(curAction, curThrowable);
-
-                    boolean exMatched = false;
-                    if (expectedExceptions != null
-                        && expectedExceptions.size() > 0) {
-                        for (Class<?> expectedException :
-                            expectedExceptions) {
-                            if (matchExpectedException(curAct, 
expectedException,
-                                curThrowable)) {
+                    if( threadId != -1 ) {
+                       // test exception on a specific thread
+                        String testExClass = null;
+                        Throwable curThrowable = null;
+                        boolean exMatched = false;
+                        TestThread exThread = threads.get(threadId);
+                        curThrowable = exThread.throwable;
+                        testExClass = processException(exThread, curAction, 
curThrowable);
+
+                        if (expectedExceptions != null
+                            && expectedExceptions.size() > 0) {
+                            for (Class<?> expectedException :
+                                expectedExceptions) {
+                                if (matchExpectedException(curAct, 
expectedException,
+                                    curThrowable)) {
+                                    exMatched = true;
+                                    break;
+                                }
+                            }
+                        } else {
+                            if (curThrowable == null) {
                                 exMatched = true;
-                                break;
                             }
                         }
-                    } else {
-                        if (curThrowable == null) {
-                            exMatched = true;
-                        }
-                    }
-                    if (!exMatched) {
-                        log.trace(testExClass);
-                        if (curThrowable != null) {
-                            logStack(curThrowable);
+                        if (!exMatched) {
+                            log.trace(testExClass);
+                            if (curThrowable != null) {
+                                logStack(curThrowable);
+                            }
                         }
+                        assertTrue(curAct + ":Expecting=" + expectedExceptions
+                            + ", Testing=" + testExClass, exMatched);
+                        exThread.throwable = null;
+                    } else {
+                       // test exception in any thread; used for deadlock 
exception testing since db server
+                       // decides on which thread to terminate if deadlock is 
detected.
+                        if (expectedExceptions == null || 
expectedExceptions.size() == 0) {
+                               // Expecting no exception in all threads.
+                               boolean noExMatched = true;
+                                                       String aTestExClass = 
"[";
+                                                       for (TestThread aThread 
: threads) {
+                                                               Throwable 
aThrowable = aThread.throwable;
+                                                               aTestExClass += 
processException(aThread, curAction, aThrowable) + ", ";
+                                                           if (aThrowable != 
null) {
+                                                               noExMatched = 
false;
+                                           log.trace(aTestExClass);
+                                       logStack(aThrowable);
+                                           aThread.throwable = null;
+                                                           }
+                                                       }
+                               assertTrue(curAct + ":Expecting=[no exception]"
+                                       + ", Testing=" + aTestExClass + ']', 
noExMatched);
+                                               } else {
+                               // Expecting any exception in any threads.
+                                                       boolean aMatched = 
false;
+                                                       String aTestExClass = 
"[";
+                                                       for (TestThread aThread 
: threads) {
+                                                               Throwable 
aThrowable = aThread.throwable;
+                                                               aTestExClass += 
processException(aThread, curAction, aThrowable) + ", ";
+
+                                                               for (Class<?> 
anExpectedException : expectedExceptions) {
+                                                                       if 
(matchExpectedException(curAct,
+                                                                               
        anExpectedException, aThrowable)) {
+                                                                               
aMatched = true;
+                                                                               
break;
+                                                                       }
+                                                               }
+                                                               if (aMatched) {
+                                                                       break;
+                                                               } else {
+                                           if (aThrowable != null) {
+                                               logStack(aThrowable);
+                                                   aThread.throwable = null;
+                                           }
+                                                               }
+                                                       }
+                               if (!aMatched) {
+                                   log.trace(aTestExClass);
+                               }
+                               assertTrue(curAct + ":Expecting=" + 
expectedExceptions
+                                   + ", Testing=" + aTestExClass + "]", 
aMatched);
+                                               }
                     }
-                    assertTrue(curAct + ":Expecting=" + expectedExceptions
-                        + ", Testing=" + testExClass, exMatched);
-                    exThread.throwable = null;
                     break;
 
                 case WaitAllChildren:
@@ -855,7 +907,7 @@ public abstract class SequencedActionsTe
                     log.trace("finally: commit completed");
                 }
                 } catch(Exception finalEx) {
-                    String failStr = processException(curAction, finalEx);
+                    String failStr = processException(thisThread, curAction, 
finalEx);
                     log.trace("Fincally:" + failStr);
                 }
             }
@@ -881,11 +933,11 @@ public abstract class SequencedActionsTe
         return lockMode;
     }
 
-    private String processException(Act curAction, Throwable t) {
-        String failStr = "Caught exception: none";
+    private String processException(TestThread thread, Act curAction, 
Throwable t) {
+        String failStr = "[" + thread.threadToRun + "] Caught exception: none";
         if (t != null) {
             getLog().trace(
-                "Caught exception: " + t.getClass().getName() + ":" + t);
+                       "[" + thread.threadToRun + "] Caught exception: " + 
t.getClass().getName() + ":" + t);
             logStack(t);
             Throwable rootCause = t.getCause();
             failStr = "Failed on action '" + curAction + "' with exception "

Modified: 
openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/TestMixedLockManagerDeadlock.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/TestMixedLockManagerDeadlock.java?rev=1072061&r1=1072060&r2=1072061&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/TestMixedLockManagerDeadlock.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/TestMixedLockManagerDeadlock.java
 Fri Feb 18 16:59:16 2011
@@ -19,6 +19,7 @@
 package org.apache.openjpa.persistence.lockmgr;
 
 import java.util.Arrays;
+import java.util.HashMap;
 
 import javax.persistence.EntityManager;
 import javax.persistence.LockModeType;
@@ -28,12 +29,14 @@ import javax.persistence.LockModeType;
  */
 public class TestMixedLockManagerDeadlock extends SequencedActionsTest {
     private DBType dbType;
+    private HashMap<DBType,Class<?>[]> expWriteLockExClasses;
     
     public void setUp() {
         setSupportedDatabases(
+                org.apache.openjpa.jdbc.sql.DB2Dictionary.class,
                 org.apache.openjpa.jdbc.sql.DerbyDictionary.class,
                 org.apache.openjpa.jdbc.sql.OracleDictionary.class,
-                org.apache.openjpa.jdbc.sql.DB2Dictionary.class);
+                org.apache.openjpa.jdbc.sql.SQLServerDictionary.class);
         if (isTestsDisabled()) {
             return;
         }
@@ -41,6 +44,12 @@ public class TestMixedLockManagerDeadloc
         setUp(LockEmployee.class
             , "openjpa.LockManager", "mixed"
         );
+        expWriteLockExClasses = new HashMap<DBType,Class<?>[]>();
+        expWriteLockExClasses.put(DBType.db2, null);
+        expWriteLockExClasses.put(DBType.derby, 
ExpectingOptimisticLockExClass);
+        expWriteLockExClasses.put(DBType.oracle, null);
+        expWriteLockExClasses.put(DBType.sqlserver, 
ExpectingOptimisticLockExClass);
+
         commonSetUp();
         EntityManager em = emf.createEntityManager();
         dbType = getDBType(em);
@@ -49,8 +58,7 @@ public class TestMixedLockManagerDeadloc
     /* ======== Find dead lock exception test ============*/
     public void testFindDeadLockException() {
         commonFindTest("testFindDeadLockException", LockModeType.READ, null); 
-        commonFindTest("testFindDeadLockException", LockModeType.WRITE, dbType 
== DBType.oracle ? null
-                : ExpectingOptimisticLockExClass);
+        commonFindTest("testFindDeadLockException", LockModeType.WRITE, 
expWriteLockExClasses.get(dbType));
         commonFindTest("testFindDeadLockException", 
LockModeType.PESSIMISTIC_WRITE, ExpectingAnyLockExClass);
     }
 
@@ -73,7 +81,7 @@ public class TestMixedLockManagerDeadloc
             {Act.FindWithLock, 2, t1Lock},                        
             
             {Act.WaitAllChildren},
-            {Act.TestException, 1, t1Exceptions},
+            {Act.TestException, -1, t1Exceptions}, // test t1Exceptions in any 
thread
             {Act.RollbackTx}
         };
         Object[][] thread1 = {
@@ -94,10 +102,8 @@ public class TestMixedLockManagerDeadloc
     /* ======== named query dead lock exception test ============*/
     public void testNamedQueryDeadLockException() {
         commonNamedQueryTest("testNamedQueryDeadLockException", 
LockModeType.READ, null);
-        commonNamedQueryTest("testNamedQueryDeadLockException", 
LockModeType.WRITE, dbType == DBType.oracle ? null
-                : ExpectingOptimisticLockExClass);
-//      commonNamedQueryTest("testNamedQueryDeadLockException", 
LockModeType.PESSIMISTIC_FORCE_INCREMENT,
-//      ExpectingAnyLockExClass);
+        commonNamedQueryTest("testNamedQueryDeadLockException", 
LockModeType.WRITE, expWriteLockExClasses.get(dbType));
+        commonNamedQueryTest("testNamedQueryDeadLockException", 
LockModeType.PESSIMISTIC_FORCE_INCREMENT, ExpectingAnyLockExClass);
     }
 
     private void commonNamedQueryTest( String testName, 
@@ -119,7 +125,7 @@ public class TestMixedLockManagerDeadloc
             {Act.NamedQueryWithLock, "findEmployeeById", 2, t1Lock, 
"openjpa.hint.IgnorePreparedQuery", true},                        
             
             {Act.WaitAllChildren},
-            {Act.TestException, 1, t1Exceptions},
+            {Act.TestException, -1, t1Exceptions},
 
             {Act.RollbackTx},
             {Act.CloseEm}

Modified: 
openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/TestPessimisticLocks.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/TestPessimisticLocks.java?rev=1072061&r1=1072060&r2=1072061&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/TestPessimisticLocks.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/TestPessimisticLocks.java
 Fri Feb 18 16:59:16 2011
@@ -137,10 +137,7 @@ public class TestPessimisticLocks extend
             em2.find(Employee.class, 2, LockModeType.PESSIMISTIC_READ, hints);
             fail("Unexcpected find succeeded. Should throw a 
PessimisticLockException.");
         } catch (Throwable e) {            
-            if (!dict.supportsLockingWithMultipleTables)
-                assertError(e, PessimisticLockException.class);
-            else 
-                assertError(e, LockTimeoutException.class);
+            assertError(e, PessimisticLockException.class, 
LockTimeoutException.class);
         } finally {
             if (em1.getTransaction().isActive())
                 em1.getTransaction().rollback();
@@ -206,10 +203,7 @@ public class TestPessimisticLocks extend
             em2.find(Employee.class, 2, LockModeType.PESSIMISTIC_READ, map);
             fail("Unexcpected find succeeded. Should throw a 
PessimisticLockException.");
         } catch (Exception e) {
-            if (!dict.supportsLockingWithMultipleTables)
-                assertError(e, PessimisticLockException.class);
-            else
-                assertError(e, LockTimeoutException.class);
+            assertError(e, PessimisticLockException.class, 
LockTimeoutException.class);
         } finally {
             if (em1.getTransaction().isActive())
                 em1.getTransaction().rollback();
@@ -276,10 +270,7 @@ public class TestPessimisticLocks extend
             assertTrue("Test department name = 'D20'", 
q.get(0).getName().equals("D10")
                     || q.get(0).getName().equals("D20"));
         } catch (Exception ex) {
-            if (!dict.supportsLockingWithMultipleTables)
-                fail("Caught unexpected " + ex.getClass().getName() + ":" + 
ex.getMessage());
-            else
-                assertError(ex, QueryTimeoutException.class);
+            assertError(ex, QueryTimeoutException.class);
         } finally {
             if (em1.getTransaction().isActive())
                 em1.getTransaction().rollback();
@@ -304,10 +295,7 @@ public class TestPessimisticLocks extend
             List<Employee> q = query.getResultList();
             fail("Unexcpected find succeeded. Should throw a 
PessimisticLockException.");
         } catch (Exception e) {
-            if (!dict.supportsLockingWithMultipleTables)
-                assertError(e, PessimisticLockException.class);
-            else
-                assertError(e, QueryTimeoutException.class);
+            assertError(e, PessimisticLockException.class, 
QueryTimeoutException.class);
         } finally {
             if (em1.getTransaction().isActive())
                 em1.getTransaction().rollback();
@@ -342,10 +330,7 @@ public class TestPessimisticLocks extend
             assertEquals("Expected 1 element with department id=20", q.size(), 
1);
             assertEquals("Test department name = 'D20'", q.get(0).getName(), 
"D20");
         } catch (Exception ex) {
-            if (!dict.supportsLockingWithMultipleTables)
-                fail("Caught unexpected " + ex.getClass().getName() + ":" + 
ex.getMessage());
-            else 
-                assertError(ex, QueryTimeoutException.class);
+            assertError(ex, QueryTimeoutException.class);
         } finally {
             if (em1.getTransaction().isActive())
                 em1.getTransaction().rollback();
@@ -370,10 +355,7 @@ public class TestPessimisticLocks extend
             List<?> q = query.getResultList();
             fail("Unexcpected find succeeded. Should throw a 
PessimisticLockException.");
         } catch (Exception e) {
-            if (!dict.supportsLockingWithMultipleTables)
-                assertError(e, PessimisticLockException.class);
-            else 
-                assertError(e, QueryTimeoutException.class);
+            assertError(e, PessimisticLockException.class, 
QueryTimeoutException.class);
         } finally {
             if (em1.getTransaction().isActive())
                 em1.getTransaction().rollback();
@@ -505,12 +487,22 @@ public class TestPessimisticLocks extend
      * @param expeceted
      *            type of the exception
      */
-    void assertError(Throwable actual, Class<? extends Throwable> expected) {
-        if (!expected.isAssignableFrom(actual.getClass())) {
-            actual.printStackTrace();
-            throw new AssertionFailedError(actual.getClass().getName() + " was 
raised but expected "
-                    + expected.getName());
-        }
+    void assertError(Throwable actual, Class<? extends Throwable> ... 
expected) {
+               boolean matched = false;
+               String expectedNames = "";
+               for (Class<? extends Throwable> aExpected : expected) {
+                       expectedNames += aExpected.getName() + ", ";
+                       if (aExpected.isAssignableFrom(actual.getClass())) {
+                               matched = true;
+                       }
+               }
+               if (!matched) {
+                       actual.printStackTrace();
+                       throw new 
AssertionFailedError(actual.getClass().getName()
+                                       + " was raised but expecting one of the 
following: ["
+                                       + expectedNames.substring(0, 
expectedNames.length() - 2) + "]");
+               }
+
         Object failed = getFailedObject(actual);
         assertNotNull("Failed object is null", failed);
         assertNotEquals("null", failed);

Modified: 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java?rev=1072061&r1=1072060&r2=1072061&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java
 Fri Feb 18 16:59:16 2011
@@ -163,10 +163,14 @@ public class EntityManagerImpl
     }
 
     public FetchPlan pushFetchPlan() {
+               return pushFetchPlan(null);
+    }
+
+    public FetchPlan pushFetchPlan(FetchConfiguration fc) {
         assertNotCloseInvoked();
         _broker.lock();
         try {
-            _broker.pushFetchConfiguration();
+            _broker.pushFetchConfiguration(fc);
             return getFetchPlan();
         } finally {
             _broker.unlock();

Modified: 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/QueryImpl.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/QueryImpl.java?rev=1072061&r1=1072060&r2=1072061&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/QueryImpl.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/QueryImpl.java
 Fri Feb 18 16:59:16 2011
@@ -316,22 +316,26 @@ public class QueryImpl<X> implements Ope
        
        public List getResultList() {
                _em.assertNotCloseInvoked();
-               Object ob = execute();
-               if (ob instanceof List) {
-                       List ret = (List) ob;
-                       if (ret instanceof ResultList) {
-                           RuntimeExceptionTranslator trans = 
PersistenceExceptions.getRollbackTranslator(_em);
-                           if (_query.isDistinct()) {
-                               return new DistinctResultList((ResultList) ret, 
trans);
+               boolean queryFetchPlanUsed = pushQueryFetchPlan();
+               try {
+                   Object ob = execute();
+                   if (ob instanceof List) {
+                           List ret = (List) ob;
+                           if (ret instanceof ResultList) {
+                               RuntimeExceptionTranslator trans = 
PersistenceExceptions.getRollbackTranslator(_em);
+                               if (_query.isDistinct()) {
+                                   return new DistinctResultList((ResultList) 
ret, trans);
+                               } else {
+                                   return new 
DelegatingResultList((ResultList) ret, trans);
+                               }
                            } else {
-                               return new DelegatingResultList((ResultList) 
ret, trans);
+                                   return ret;
                            }
-                       } else {
-                               return ret;
-                       }
+                   }
+                   return Collections.singletonList(ob);
+               } finally {
+                       popQueryFetchPlan(queryFetchPlanUsed);
                }
-
-               return Collections.singletonList(ob);
        }
 
        /**
@@ -340,18 +344,45 @@ public class QueryImpl<X> implements Ope
        public X getSingleResult() {
                _em.assertNotCloseInvoked();
         setHint(QueryHints.HINT_RESULT_COUNT, 1); // for DB2 optimization
-               List result = getResultList();
-               if (result == null || result.isEmpty())
-            throw new NoResultException(_loc.get("no-result", getQueryString())
-                    .getMessage());
-               if (result.size() > 1)
-            throw new NonUniqueResultException(_loc.get("non-unique-result",
-                    getQueryString(), result.size()).getMessage());
+               boolean queryFetchPlanUsed = pushQueryFetchPlan();
                try {
-                   return (X)result.get(0);
-               } catch (Exception e) {
-            throw new NoResultException(_loc.get("no-result", getQueryString())
-                .getMessage());
+                   List result = getResultList();
+                   if (result == null || result.isEmpty())
+                throw new NoResultException(_loc.get("no-result", 
getQueryString())
+                        .getMessage());
+                   if (result.size() > 1)
+                throw new 
NonUniqueResultException(_loc.get("non-unique-result",
+                        getQueryString(), result.size()).getMessage());
+                   try {
+                       return (X)result.get(0);
+                   } catch (Exception e) {
+                throw new NoResultException(_loc.get("no-result", 
getQueryString())
+                    .getMessage());
+                   }
+               } finally {
+                       popQueryFetchPlan(queryFetchPlanUsed);
+               }
+       }
+
+       private boolean pushQueryFetchPlan() {
+               boolean fcPushed = false;
+               if (_fetch != null && _hintHandler != null) {
+                       switch (_fetch.getReadLockMode()) {
+                       case PESSIMISTIC_READ:
+                       case PESSIMISTIC_WRITE:
+                       case PESSIMISTIC_FORCE_INCREMENT:
+                               // push query fetch plan to em if pessisimistic 
lock and any
+                               // hints are set
+                               
_em.pushFetchPlan(((FetchPlanImpl)_fetch).getDelegate());
+                               fcPushed = true;
+                       }
+               }
+               return fcPushed;
+       }
+
+       private void popQueryFetchPlan(boolean queryFetchPlanUsed) {
+               if (queryFetchPlanUsed) {
+                       _em.popFetchPlan();
                }
        }
 


Reply via email to