You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pp...@apache.org on 2009/03/10 08:22:24 UTC

svn commit: r752005 - in /openjpa/trunk: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/ openjpa-kernel/src/main/java/org/apache/openjpa/conf/ openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ openjpa-persistence-jdbc/src/test/java/org...

Author: ppoddar
Date: Tue Mar 10 07:22:23 2009
New Revision: 752005

URL: http://svn.apache.org/viewvc?rev=752005&view=rev
Log:
OPENJPA-958,959: timeout on query

Modified:
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/DataSourceFactory.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfiguration.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingFetchConfiguration.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfiguration.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfigurationImpl.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/conf/TestQueryHints.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.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/FetchPlan.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/FetchPlanImpl.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/HintHandler.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/JPA2LockLevels.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/QueryImpl.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/DataSourceFactory.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/DataSourceFactory.java?rev=752005&r1=752004&r2=752005&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/DataSourceFactory.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/DataSourceFactory.java Tue Mar 10 07:22:23 2009
@@ -209,6 +209,8 @@
             ConfiguringConnectionDecorator ccd =
                 new ConfiguringConnectionDecorator();
             ccd.setTransactionIsolation(conf.getTransactionIsolationConstant());
+            ccd.setQueryTimeout(conf.getQueryTimeout() == -1 
+                ? -1 : conf.getQueryTimeout() * 1000);
             Log log = conf.getLog(JDBCConfiguration.LOG_JDBC);
             if (factory2 || !conf.isConnectionFactoryModeManaged()) {
                 if (!dict.supportsMultipleNontransactionalResultSets)

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfiguration.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfiguration.java?rev=752005&r1=752004&r2=752005&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfiguration.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfiguration.java Tue Mar 10 07:22:23 2009
@@ -1200,6 +1200,22 @@
     public void setLockTimeout(Integer timeout);
 
     /**
+     * The time to wait for a query to execute in milliseconds, or -1 for no
+     * timeout.
+     *
+     * @since 2.0.0
+     */
+    public int getQueryTimeout();
+
+    /**
+     * The time to wait for a query to execute in milliseconds, or -1 for no
+     * timeout.
+     *
+     * @since 0.3.1
+     */
+    public void setQueryTimeout(int timeout);
+
+    /**
      * The default read lock level to use during non-optimistic transactions.
      * Defaults to <code>read</code>.
      *

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java?rev=752005&r1=752004&r2=752005&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java Tue Mar 10 07:22:23 2009
@@ -101,6 +101,7 @@
     public StringListValue fetchGroups;
     public IntValue flushBeforeQueries;
     public IntValue lockTimeout;
+    public IntValue queryTimeout;
     public IntValue readLockLevel;
     public IntValue writeLockLevel;
     public ObjectValue seqPlugin;
@@ -151,7 +152,6 @@
     public PluginValue preparedQueryCachePlugin;
     public PluginValue finderCachePlugin;
     public ObjectValue specification;
-    public IntValue queryTimeout;
     
     // custom values
     public BrokerFactoryValue brokerFactoryPlugin;
@@ -550,7 +550,6 @@
         specification.setInstantiatingGetter("getSpecificationInstance");
         
         queryTimeout = addInt("javax.persistence.query.timeout");
-        queryTimeout.addEquivalentKey("javax.persistence.query.timeout");
         queryTimeout.setDefault("-1");
         queryTimeout.setDynamic(true);
         
@@ -1311,6 +1310,14 @@
         return lockTimeout.get();
     }
 
+    public int getQueryTimeout() {
+        return queryTimeout.get();
+    }
+    
+    public void setQueryTimeout(int timeout) {
+         queryTimeout.set(timeout);
+    }
+
     public void setReadLockLevel(String level) {
         readLockLevel.setString(level);
     }

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=752005&r1=752004&r2=752005&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 Tue Mar 10 07:22:23 2009
@@ -714,7 +714,6 @@
             _supportedPropertyNames.add("NontransactionalRead");
             _supportedPropertyNames.add("NontransactionalWrite");
             _supportedPropertyNames.add("Optimistic");
-            _supportedPropertyNames.add("javax.persistence.query.timeout");
             _supportedPropertyNames.add("RestoreState");
             _supportedPropertyNames.add("RetainState");
         }
@@ -722,6 +721,8 @@
         for (String propertyName : _supportedPropertyNames) {
             supportedProperties.addAll(_conf.getPropertyKeys(propertyName));
         }
+        supportedProperties.add("javax.persistence.query.timeout");
+        supportedProperties.add("javax.persistence.lock.timeout");
         
         return supportedProperties;
     }

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingFetchConfiguration.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingFetchConfiguration.java?rev=752005&r1=752004&r2=752005&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingFetchConfiguration.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingFetchConfiguration.java Tue Mar 10 07:22:23 2009
@@ -366,7 +366,7 @@
             throw translate(re);
         }
     }
-
+    
     public int getLockTimeout() {
         try {
             return _fetch.getLockTimeout();
@@ -384,6 +384,23 @@
         }
     }
 
+    public int getQueryTimeout() {
+        try {
+            return _fetch.getQueryTimeout();
+        } catch (RuntimeException re) {
+            throw translate(re);
+        }
+    }
+
+    public FetchConfiguration setQueryTimeout(int timeout) {
+        try {
+            _fetch.setQueryTimeout(timeout);
+            return this;
+        } catch (RuntimeException re) {
+            throw translate(re);
+        }
+    }
+
     public int getReadLockLevel() {
         try {
             return _fetch.getReadLockLevel();

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfiguration.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfiguration.java?rev=752005&r1=752004&r2=752005&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfiguration.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfiguration.java Tue Mar 10 07:22:23 2009
@@ -268,6 +268,22 @@
      * @since 0.3.1
      */
     public FetchConfiguration setLockTimeout(int timeout);
+    
+    /**
+     * The number of milliseconds to wait for a query, or -1 for no
+     * limit.
+     *
+     * @since 2.0.0
+     */
+    public int getQueryTimeout();
+
+    /**
+     * The number of milliseconds to wait for a query, or -1 for no
+     * limit.
+     *
+     * @since 2.0.0
+     */
+    public FetchConfiguration setQueryTimeout(int timeout);
 
     /**
      * The lock level to use for locking loaded objects.

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfigurationImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfigurationImpl.java?rev=752005&r1=752004&r2=752005&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfigurationImpl.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfigurationImpl.java Tue Mar 10 07:22:23 2009
@@ -76,6 +76,8 @@
         public boolean queryCache = true;
         public int flushQuery = 0;
         public int lockTimeout = -1;
+        public int queryTimeout = -1;
+        public int lockMode = 0;
         public int readLockLevel = LOCK_NONE;
         public int writeLockLevel = LOCK_NONE;
         public Set fetchGroups = null;
@@ -159,6 +161,7 @@
         setFlushBeforeQueries(fetch.getFlushBeforeQueries());
         setExtendedPathLookup(fetch.getExtendedPathLookup());
         setLockTimeout(fetch.getLockTimeout());
+        setQueryTimeout(fetch.getQueryTimeout());
         clearFetchGroups();
         addFetchGroups(fetch.getFetchGroups());
         clearFields();
@@ -423,8 +426,29 @@
             _state.lockTimeout = timeout;
         return this;
     }
+    
+    public int getQueryTimeout() {
+        return _state.queryTimeout;
+    }
+
+    public FetchConfiguration setQueryTimeout(int timeout) {
+        if (timeout == DEFAULT && _state.ctx != null)
+            _state.queryTimeout = _state.ctx.getConfiguration().getQueryTimeout();
+        else if (timeout != DEFAULT)
+            _state.queryTimeout = timeout;
+        return this;
+    }
+
 
     public int getReadLockLevel() {
+        String hintKey = "openjpa.FetchPlan.ReadLockLevel";
+        if (getHint(hintKey) != null) {
+            if (isActiveTransaction()) {
+                setReadLockLevel((Integer)removeHint(hintKey));
+            } else {
+                return (Integer)getHint(hintKey);
+            }
+        }
         return _state.readLockLevel;
     }
 
@@ -447,6 +471,14 @@
     }
 
     public int getWriteLockLevel() {
+        String hintKey = "openjpa.FetchPlan.WriteLockLevel";
+        if (getHint(hintKey) != null) {
+            if (isActiveTransaction()) {
+                setReadLockLevel((Integer)removeHint(hintKey));
+            } else {
+                return (Integer)getHint(hintKey);
+            }
+        }
         return _state.writeLockLevel;
     }
 
@@ -482,9 +514,13 @@
      * Throw an exception if no transaction is active.
      */
     private void assertActiveTransaction() {
-        if (_state.ctx != null && !_state.ctx.isActive())
+        if (!isActiveTransaction())
             throw new NoTransactionException(_loc.get("not-active"));
     }
+    
+    private boolean isActiveTransaction() {
+        return (_state.ctx != null && _state.ctx.isActive());
+    }
 
     public void setHint(String name, Object value) {
         lock();
@@ -501,6 +537,10 @@
         return (_state.hints == null) ? null : _state.hints.get(name);
     }
     
+    public Object removeHint(String name) {
+        return (_state.hints == null) ? null : _state.hints.remove(name);
+    }
+    
     public Map<String, Object> getHints() {
         if (_state.hints == null)
             return (Map<String, Object>)Collections.EMPTY_MAP;

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/conf/TestQueryHints.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/conf/TestQueryHints.java?rev=752005&r1=752004&r2=752005&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/conf/TestQueryHints.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/conf/TestQueryHints.java Tue Mar 10 07:22:23 2009
@@ -139,7 +139,7 @@
     public void testJPAHintSetsFetchPlan() {
         String jpaKey = "javax.persistence.query.timeout";
         query.setHint(jpaKey, 5671);
-        assertEquals(5671, query.getFetchPlan().getLockTimeout());
+        assertEquals(5671, query.getFetchPlan().getQueryTimeout());
     }
     
     public void testParts() {

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java?rev=752005&r1=752004&r2=752005&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java Tue Mar 10 07:22:23 2009
@@ -18,6 +18,53 @@
  */
 package org.apache.openjpa.persistence;
 
+import static javax.persistence.GenerationType.AUTO;
+import static org.apache.openjpa.persistence.MetaDataTag.DATASTORE_ID;
+import static org.apache.openjpa.persistence.MetaDataTag.DATA_CACHE;
+import static org.apache.openjpa.persistence.MetaDataTag.DEPENDENT;
+import static org.apache.openjpa.persistence.MetaDataTag.DETACHED_STATE;
+import static org.apache.openjpa.persistence.MetaDataTag.ELEM_DEPENDENT;
+import static org.apache.openjpa.persistence.MetaDataTag.ELEM_TYPE;
+import static org.apache.openjpa.persistence.MetaDataTag.EMBEDDED_ID;
+import static org.apache.openjpa.persistence.MetaDataTag.ENTITY_LISTENERS;
+import static org.apache.openjpa.persistence.MetaDataTag.EXCLUDE_DEFAULT_LISTENERS;
+import static org.apache.openjpa.persistence.MetaDataTag.EXCLUDE_SUPERCLASS_LISTENERS;
+import static org.apache.openjpa.persistence.MetaDataTag.EXTERNALIZER;
+import static org.apache.openjpa.persistence.MetaDataTag.EXTERNAL_VALS;
+import static org.apache.openjpa.persistence.MetaDataTag.FACTORY;
+import static org.apache.openjpa.persistence.MetaDataTag.FETCH_GROUP;
+import static org.apache.openjpa.persistence.MetaDataTag.FETCH_GROUPS;
+import static org.apache.openjpa.persistence.MetaDataTag.FLUSH_MODE;
+import static org.apache.openjpa.persistence.MetaDataTag.GENERATED_VALUE;
+import static org.apache.openjpa.persistence.MetaDataTag.ID;
+import static org.apache.openjpa.persistence.MetaDataTag.ID_CLASS;
+import static org.apache.openjpa.persistence.MetaDataTag.INVERSE_LOGICAL;
+import static org.apache.openjpa.persistence.MetaDataTag.KEY_DEPENDENT;
+import static org.apache.openjpa.persistence.MetaDataTag.KEY_TYPE;
+import static org.apache.openjpa.persistence.MetaDataTag.LOAD_FETCH_GROUP;
+import static org.apache.openjpa.persistence.MetaDataTag.LRS;
+import static org.apache.openjpa.persistence.MetaDataTag.MANAGED_INTERFACE;
+import static org.apache.openjpa.persistence.MetaDataTag.MAPPED_BY_ID;
+import static org.apache.openjpa.persistence.MetaDataTag.MAP_KEY;
+import static org.apache.openjpa.persistence.MetaDataTag.MAP_KEY_CLASS;
+import static org.apache.openjpa.persistence.MetaDataTag.NATIVE_QUERIES;
+import static org.apache.openjpa.persistence.MetaDataTag.NATIVE_QUERY;
+import static org.apache.openjpa.persistence.MetaDataTag.ORDER_BY;
+import static org.apache.openjpa.persistence.MetaDataTag.POST_LOAD;
+import static org.apache.openjpa.persistence.MetaDataTag.POST_PERSIST;
+import static org.apache.openjpa.persistence.MetaDataTag.POST_REMOVE;
+import static org.apache.openjpa.persistence.MetaDataTag.POST_UPDATE;
+import static org.apache.openjpa.persistence.MetaDataTag.PRE_PERSIST;
+import static org.apache.openjpa.persistence.MetaDataTag.PRE_REMOVE;
+import static org.apache.openjpa.persistence.MetaDataTag.PRE_UPDATE;
+import static org.apache.openjpa.persistence.MetaDataTag.QUERIES;
+import static org.apache.openjpa.persistence.MetaDataTag.QUERY;
+import static org.apache.openjpa.persistence.MetaDataTag.READ_ONLY;
+import static org.apache.openjpa.persistence.MetaDataTag.REPLICATED;
+import static org.apache.openjpa.persistence.MetaDataTag.SEQ_GENERATOR;
+import static org.apache.openjpa.persistence.MetaDataTag.TYPE;
+import static org.apache.openjpa.persistence.MetaDataTag.VERSION;
+
 import java.io.File;
 import java.io.Serializable;
 import java.lang.annotation.Annotation;
@@ -38,8 +85,10 @@
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeSet;
+
 import javax.persistence.Basic;
 import javax.persistence.CascadeType;
+import javax.persistence.ElementCollection;
 import javax.persistence.Embeddable;
 import javax.persistence.Embedded;
 import javax.persistence.EmbeddedId;
@@ -51,8 +100,6 @@
 import javax.persistence.FlushModeType;
 import javax.persistence.GeneratedValue;
 import javax.persistence.GenerationType;
-import static javax.persistence.GenerationType.AUTO;
-import javax.persistence.ElementCollection;
 import javax.persistence.Id;
 import javax.persistence.IdClass;
 import javax.persistence.Lob;
@@ -106,8 +153,6 @@
 import org.apache.openjpa.meta.UpdateStrategies;
 import org.apache.openjpa.meta.ValueMetaData;
 import org.apache.openjpa.meta.ValueStrategies;
-import org.apache.openjpa.meta.MetaDataDefaults;
-import static org.apache.openjpa.persistence.MetaDataTag.*;
 import org.apache.openjpa.util.ImplHelper;
 import org.apache.openjpa.util.InternalException;
 import org.apache.openjpa.util.MetaDataException;
@@ -1673,6 +1718,7 @@
             meta = getRepository().addQueryMetaData(_cls, query.name());
             meta.setQueryString(query.query());
             meta.setLanguage(JPQLParser.LANG_JPQL);
+            meta.addHint("openjpa.FetchPlan.ReadLockMode", query.lockMode());
             for (QueryHint hint : query.hints())
                 meta.addHint(hint.name(), hint.value());
 

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=752005&r1=752004&r2=752005&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 Tue Mar 10 07:22:23 2009
@@ -1073,12 +1073,12 @@
 
     public LockModeType getLockMode(Object entity) {
         assertNotCloseInvoked();
-        return fromLockLevel(_broker.getLockLevel(entity));
+        return JPA2LockLevels.fromLockLevel(_broker.getLockLevel(entity));
     }
 
     public void lock(Object entity, LockModeType mode) {
         assertNotCloseInvoked();
-        _broker.lock(entity, toLockLevel(mode), -1, this);
+        _broker.lock(entity, JPA2LockLevels.toLockLevel(mode), -1, this);
     }
 
     public void lock(Object entity) {
@@ -1088,7 +1088,7 @@
 
     public void lock(Object entity, LockModeType mode, int timeout) {
         assertNotCloseInvoked();
-        _broker.lock(entity, toLockLevel(mode), timeout, this);
+        _broker.lock(entity, JPA2LockLevels.toLockLevel(mode), timeout, this);
     }
 
     public void lock(Object entity, LockModeType mode,
@@ -1098,7 +1098,7 @@
 
         boolean fcPushed = pushLockProperties(mode, properties);
         try {
-            _broker.lock(entity, toLockLevel(mode), _broker
+            _broker.lock(entity, JPA2LockLevels.toLockLevel(mode), _broker
                 .getFetchConfiguration().getLockTimeout(), this);
         } finally {
             popLockProperties(fcPushed);
@@ -1112,7 +1112,7 @@
 
     public void lockAll(Collection entities, LockModeType mode, int timeout) {
         assertNotCloseInvoked();
-        _broker.lockAll(entities, toLockLevel(mode), timeout, this);
+        _broker.lockAll(entities, JPA2LockLevels.toLockLevel(mode), timeout, this);
     }
 
     public void lockAll(Object... entities) {
@@ -1123,45 +1123,6 @@
         lockAll(Arrays.asList(entities), mode, timeout);
     }
 
-    /**
-     * Translate our internal lock level to a javax.persistence enum value.
-     */
-    static LockModeType fromLockLevel(int level) {
-        if (level < JPA2LockLevels.LOCK_OPTIMISTIC)
-            return null;
-        if (level < JPA2LockLevels.LOCK_OPTIMISTIC_FORCE_INCREMENT)
-            return LockModeType.READ;
-        if (level < JPA2LockLevels.LOCK_PESSIMISTIC_READ)
-            return LockModeType.WRITE;
-        if (level < JPA2LockLevels.LOCK_PESSIMISTIC_WRITE)
-            return LockModeType.PESSIMISTIC;
-// TODO:         return LockModeType.PESSIMISTIC_READ;
-        if (level < JPA2LockLevels.LOCK_PESSIMISTIC_FORCE_INCREMENT)
-            return LockModeType.PESSIMISTIC;
-// TODO:         return LockModeType.PESSIMISTIC_WRITE;
-        return LockModeType.PESSIMISTIC_FORCE_INCREMENT;
-    }
-
-    /**
-     * Translate the javax.persistence enum value to our internal lock level.
-     */
-    static int toLockLevel(LockModeType mode) {
-        if (mode == null || mode == LockModeType.NONE)
-            return LockLevels.LOCK_NONE;
-        if (mode == LockModeType.READ || mode == LockModeType.OPTIMISTIC)
-            return LockLevels.LOCK_READ;
-        if (mode == LockModeType.WRITE
-            || mode == LockModeType.OPTIMISTIC_FORCE_INCREMENT)
-            return LockLevels.LOCK_WRITE;
-// TODO:      if (mode == LockModeType.PESSIMISTIC_READ)
-// TODO:         return LockLevels.LOCK_PESSIMISTIC_READ;
-        if (mode == LockModeType.PESSIMISTIC)
-            return JPA2LockLevels.LOCK_PESSIMISTIC_WRITE;
-        if (mode == LockModeType.PESSIMISTIC_FORCE_INCREMENT)
-            return JPA2LockLevels.LOCK_PESSIMISTIC_FORCE_INCREMENT;
-        throw new ArgumentException(mode.toString(), null, null, true);
-    }
-
     public boolean cancelAll() {
         return _broker.cancelAll();
     }
@@ -1633,7 +1594,7 @@
                 FetchConfigProperty.WriteLockLevel }, properties);
         }
         // override with the specific lockMode, if needed.
-        int setReadLevel = toLockLevel(mode);
+        int setReadLevel = JPA2LockLevels.toLockLevel(mode);
         if (setReadLevel != JPA2LockLevels.LOCK_NONE) {
             // Set overriden read lock level
             FetchConfiguration fCfg = _broker.getFetchConfiguration();

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/FetchPlan.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/FetchPlan.java?rev=752005&r1=752004&r2=752005&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/FetchPlan.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/FetchPlan.java Tue Mar 10 07:22:23 2009
@@ -267,11 +267,23 @@
     public int getLockTimeout();
 
     /**
+     * The number of milliseconds to wait for a query, or -1 for no
+     * limit.
+     */
+    public FetchPlan setQueryTimeout(int timeout);
+
+    /**
+     * The number of milliseconds to wait for a query, or -1 for no
+     * limit.
+     */
+    public int getQueryTimeout();
+
+    /**
      * The number of milliseconds to wait for an object lock, or -1 for no
      * limit.
      */
-    public FetchPlan setLockTimeout(int timeout);
 
+    public FetchPlan setLockTimeout(int timeout);
     /**
      * The lock level to use for locking loaded objects.
      */
@@ -291,6 +303,7 @@
      * The lock level to use for locking dirtied objects.
      */
     public FetchPlan setWriteLockMode(LockModeType mode);
+    
 
     /**
      * @deprecated cast to {@link FetchPlanImpl} instead. This

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/FetchPlanImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/FetchPlanImpl.java?rev=752005&r1=752004&r2=752005&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/FetchPlanImpl.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/FetchPlanImpl.java Tue Mar 10 07:22:23 2009
@@ -232,21 +232,30 @@
         return this;
     }
 
+    public int getQueryTimeout() {
+        return _fetch.getQueryTimeout();
+    }
+
+    public FetchPlan setQueryTimeout(int timeout) {
+        _fetch.setQueryTimeout(timeout);
+        return this;
+    }
+
     public LockModeType getReadLockMode() {
-        return EntityManagerImpl.fromLockLevel(_fetch.getReadLockLevel());
+        return JPA2LockLevels.fromLockLevel(_fetch.getReadLockLevel());
     }
 
     public FetchPlan setReadLockMode(LockModeType mode) {
-        _fetch.setReadLockLevel(EntityManagerImpl.toLockLevel(mode));
+        _fetch.setReadLockLevel(JPA2LockLevels.toLockLevel(mode));
         return this;
     }
 
     public LockModeType getWriteLockMode() {
-        return EntityManagerImpl.fromLockLevel(_fetch.getWriteLockLevel());
+        return JPA2LockLevels.fromLockLevel(_fetch.getWriteLockLevel());
     }
 
     public FetchPlan setWriteLockMode(LockModeType mode) {
-        _fetch.setWriteLockLevel(EntityManagerImpl.toLockLevel(mode));
+        _fetch.setWriteLockLevel(JPA2LockLevels.toLockLevel(mode));
         return this;
     }
     

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/HintHandler.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/HintHandler.java?rev=752005&r1=752004&r2=752005&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/HintHandler.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/HintHandler.java Tue Mar 10 07:22:23 2009
@@ -106,6 +106,8 @@
     public static Map<String,String> _jpaKeys = new TreeMap<String, String>();
     static {
         _jpaKeys.put(addPrefix(PREFIX_JPA, "query.timeout"), 
+            addPrefix(PREFIX_FETCHPLAN, "QueryTimeout"));
+        _jpaKeys.put(addPrefix(PREFIX_JPA, "lock.timeout"), 
             addPrefix(PREFIX_FETCHPLAN, "LockTimeout"));
     }
     
@@ -299,8 +301,12 @@
                 for (int i = 0; i < arr.length; i++)
                     owner.addAggregateListener(arr[i]);
             } else if (isFetchPlanHint(key)) {
-                hintToSetter(owner.getFetchPlan(), 
-                    getFetchPlanProperty(key), value);
+                if (requiresTransaction(key))
+                    ((FetchPlanImpl)owner.getFetchPlan()).getDelegate()
+                        .setHint(key, value);
+                else 
+                    hintToSetter(owner.getFetchPlan(), 
+                        getFetchPlanProperty(key), value);
             } else if (HINT_RESULT_COUNT.equals(key)) {
                 int v = (Integer)Filters.convert(value, Integer.class);
                 if (v < 0)
@@ -333,6 +339,10 @@
            || (_jpaKeys.containsKey(key) && isFetchPlanHint(_jpaKeys.get(key)));
     }
     
+    private boolean requiresTransaction(String key) {
+        return key.endsWith("LockMode");
+    }
+    
     private String getFetchPlanProperty(String key) {
         if (key.startsWith(PREFIX_FETCHPLAN))
             return removePrefix(key, PREFIX_FETCHPLAN);

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/JPA2LockLevels.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/JPA2LockLevels.java?rev=752005&r1=752004&r2=752005&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/JPA2LockLevels.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/JPA2LockLevels.java Tue Mar 10 07:22:23 2009
@@ -18,25 +18,43 @@
  */
 package org.apache.openjpa.persistence;
 
+import javax.persistence.LockModeType;
+
 import org.apache.openjpa.kernel.LockLevels;
 
 /**
- * Standard object lock levels.
- *
+ * Defines lock levels as per JPA 2.0 specification.
+ * 
+ * Translates JPA-defined lock levels and OpenJPA internal lock levels.
+ * 
  * @author Albert Lee
  * @since 2.0.0
  */
-public interface JPA2LockLevels extends LockLevels{
+public class JPA2LockLevels {
+    /**
+     * Generic optimistic no lock level. Defined since JPA 1.0.
+     * 
+     */
+    public static final int LOCK_NONE = LockLevels.LOCK_NONE;
 
     /**
-     * Generic optimistic read lock level. Value of 10.
+     * Generic optimistic read lock level. Defined since JPA 1.0.
+     * Equivalent to <code>LOCK_OPTIMISTIC</code> which is preferred.
+     */
+    public static final int LOCK_READ = LockLevels.LOCK_READ;
+    
+    /**
+     * Generic optimistic read lock level. Defined since JPA 2.0.
+     * Value of 10.
+     * 
      */
     public static final int LOCK_OPTIMISTIC = LOCK_READ;
 
     /**
      * Generic optimistic write lock level. Value of 20.
      */
-    public static final int LOCK_OPTIMISTIC_FORCE_INCREMENT = LOCK_WRITE;
+    public static final int LOCK_OPTIMISTIC_FORCE_INCREMENT = 
+        LockLevels.LOCK_WRITE;
 
     /**
      * Generic pessimistic read lock level. Value of 30.
@@ -53,4 +71,42 @@
      */
     public static final int LOCK_PESSIMISTIC_FORCE_INCREMENT = 50;
 
+    /**
+     * Translates the javax.persistence enum value to our internal lock level.
+     */
+    public static int toLockLevel(LockModeType mode) {
+        if (mode == null || mode == LockModeType.NONE)
+            return LockLevels.LOCK_NONE;
+        if (mode == LockModeType.READ || mode == LockModeType.OPTIMISTIC)
+            return LockLevels.LOCK_READ;
+        if (mode == LockModeType.WRITE
+            || mode == LockModeType.OPTIMISTIC_FORCE_INCREMENT)
+            return LockLevels.LOCK_WRITE;
+        // TODO: if (mode == LockModeType.PESSIMISTIC_READ)
+        // TODO: return LockLevels.LOCK_PESSIMISTIC_READ;
+        if (mode == LockModeType.PESSIMISTIC)
+            return LOCK_PESSIMISTIC_WRITE;
+        if (mode == LockModeType.PESSIMISTIC_FORCE_INCREMENT)
+            return LOCK_PESSIMISTIC_FORCE_INCREMENT;
+        throw new ArgumentException(mode.toString(), null, null, true);
+    }
+
+    /**
+     * Translate our internal lock level to a javax.persistence enum value.
+     */
+    public static LockModeType fromLockLevel(int level) {
+        if (level < LOCK_OPTIMISTIC)
+            return null;
+        if (level < LOCK_OPTIMISTIC_FORCE_INCREMENT)
+            return LockModeType.READ;
+        if (level < LOCK_PESSIMISTIC_READ)
+            return LockModeType.WRITE;
+        if (level < LOCK_PESSIMISTIC_WRITE)
+            return LockModeType.PESSIMISTIC;
+        // TODO: return LockModeType.PESSIMISTIC_READ;
+        if (level < LOCK_PESSIMISTIC_FORCE_INCREMENT)
+            return LockModeType.PESSIMISTIC;
+        // TODO: return LockModeType.PESSIMISTIC_WRITE;
+        return LockModeType.PESSIMISTIC_FORCE_INCREMENT;
+    }
 }

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=752005&r1=752004&r2=752005&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 Tue Mar 10 07:22:23 2009
@@ -72,7 +72,7 @@
 public class QueryImpl implements OpenJPAQuerySPI, Serializable {
 
     private static final List EMPTY_LIST = new ArrayList(0);
-
+    private static final String SELECT = "SELECT ";
 	private static final Localizer _loc = Localizer.forPackage(QueryImpl.class);
 
 	private DelegatingQuery _query;
@@ -354,12 +354,6 @@
 		return this;
 	}
 
-	public OpenJPAQuery setHint(String key, Object value) {
-		_em.assertNotCloseInvoked();
-		_hintHandler.setHint(key, value);
-		return this;
-	}
-
 	public OpenJPAQuery setParameter(int position, Calendar value,
 			TemporalType t) {
 		return setParameter(position, convertTemporalType(value, t));
@@ -527,6 +521,20 @@
 		return _query.getDataStoreActions(params);
 	}
 
+    public LockModeType getLockMode() {
+        assertQueryLanguage(JPQLParser.LANG_JPQL, 
+            QueryLanguages.LANG_PREPARED_SQL);
+        return _fetch.getReadLockMode();
+    }
+
+    public Query setLockMode(LockModeType lockMode) {
+        assertQueryLanguage(JPQLParser.LANG_JPQL, 
+            QueryLanguages.LANG_PREPARED_SQL);
+    
+       _fetch.setReadLockMode(lockMode);
+       return this;
+    }
+
 	public int hashCode() {
 		return _query.hashCode();
 	}
@@ -548,20 +556,16 @@
         return _hintHandler.getHints();
     }
 
-    public LockModeType getLockMode() {
-        throw new UnsupportedOperationException(
-            "JPA 2.0 - Method not yet implemented");
+    public OpenJPAQuery setHint(String key, Object value) {
+        _em.assertNotCloseInvoked();
+        _hintHandler.setHint(key, value);
+        return this;
     }
 
     public Set<String> getSupportedHints() {
         return _hintHandler.getSupportedHints();
     }
 
-    public Query setLockMode(LockModeType lockMode) {
-        throw new UnsupportedOperationException(
-            "JPA 2.0 - Method not yet implemented");
-    }
-
     /**
      * Returns the innermost implementation that is an instance of the given 
      * class. 
@@ -684,14 +688,26 @@
         return this;
     }
     
-    public void lock() {
+    void lock() {
         if (_lock != null) 
             _lock.lock();
     }
 
-    public void unlock() {
+    void unlock() {
         if (_lock != null)
             _lock.unlock();
     }
 
+    void assertQueryLanguage(String... langs) {
+        for (String lang : langs) {
+            if (lang.equals(getLanguage())) {
+                String q = _query.getQueryString();
+                if (q != null && q.length() > SELECT.length() 
+                 && SELECT.equalsIgnoreCase(q.substring(SELECT.length())))
+                 return;
+            }
+        }
+        throw new IllegalStateException(_loc.get("assert-query-language",
+            getLanguage()).toString());
+    }
 }

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java?rev=752005&r1=752004&r2=752005&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java Tue Mar 10 07:22:23 2009
@@ -35,6 +35,8 @@
 import java.util.Stack;
 import javax.persistence.CascadeType;
 import javax.persistence.GenerationType;
+import javax.persistence.LockModeType;
+
 import static javax.persistence.CascadeType.*;
 
 import org.apache.commons.lang.StringUtils;
@@ -1565,6 +1567,11 @@
         meta.setDefiningType(_cls);
         meta.setQueryString(attrs.getValue("query"));
         meta.setLanguage(JPQLParser.LANG_JPQL);
+        /** TODO: Uncomment when orm.xsd defines lockmode 
+        LockModeType lockMode = LockModeType.valueOf(attrs.getValue("lockMode"));
+        meta.addHint("openjpa.FetchPlan.ReadLockMode", 
+            JPA2LockLevels.toLockLevel(lockMode));
+        **/
         Locator locator = getLocation().getLocator();
         if (locator != null) {
             meta.setLineNumber(Numbers.valueOf(locator.getLineNumber()));