Author: ppoddar
Date: Thu Apr 1 17:23:46 2010
New Revision: 930049
URL: http://svn.apache.org/viewvc?rev=930049&view=rev
Log:
OPENJPA-1604: Test for lock mode on named query and its impact on target SQL
under pessimistic lock manager plus some usability changes. Does not restore
backward compatibility with 1.2 behavior -- but removes the need to set the
fecth plan hint etc and ensures named query lock mode other than NONE requires
an active transaction.
Added:
openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/TestNamedQueryLockMode.java
(with props)
Modified:
openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/LockEmployee.java
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java
openjpa/trunk/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties
Modified:
openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/LockEmployee.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/LockEmployee.java?rev=930049&r1=930048&r2=930049&view=diff
==============================================================================
---
openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/LockEmployee.java
(original)
+++
openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/LockEmployee.java
Thu Apr 1 17:23:46 2010
@@ -25,13 +25,22 @@ import java.io.ObjectOutput;
import javax.persistence.Entity;
import javax.persistence.Id;
+import javax.persistence.LockModeType;
+import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Version;
-...@namedquery(
- name="findEmployeeById"
- , query="SELECT c FROM LockEmployee c WHERE c.id = :id"
- )
+
+...@namedqueries({
+ @NamedQuery(name="findEmployeeById",
+ query="SELECT c FROM LockEmployee c WHERE c.id = :id"),
+ @NamedQuery(name="findEmployeeByIdWithLock",
+ query="SELECT c FROM LockEmployee c WHERE c.id = :id",
+ lockMode=LockModeType.PESSIMISTIC_READ),
+ @NamedQuery(name="findEmployeeByIdWithNoLock",
+ query="SELECT c FROM LockEmployee c WHERE c.id = :id",
+ lockMode=LockModeType.NONE)
+ })
@Entity
public class LockEmployee implements Externalizable {
Added:
openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/TestNamedQueryLockMode.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/TestNamedQueryLockMode.java?rev=930049&view=auto
==============================================================================
---
openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/TestNamedQueryLockMode.java
(added)
+++
openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/TestNamedQueryLockMode.java
Thu Apr 1 17:23:46 2010
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.lockmgr;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+import javax.persistence.TransactionRequiredException;
+
+import org.apache.openjpa.persistence.test.SQLListenerTestCase;
+
+/**
+ * Tests the lock mode on named query emits a FOR UPDATE clause in target SQL
query.
+ *
+ * @author Pinaki Poddar
+ *
+ */
+public class TestNamedQueryLockMode extends SQLListenerTestCase {
+ public void setUp() {
+ super.setUp(CLEAR_TABLES, LockEmployee.class,
+ "openjpa.LockManager", "pessimistic",
+ "openjpa.Optimistic", "false");
+ }
+
+ public void testForUpdateClausePresentInNamedQueryWithLockMode() {
+ EntityManager em = emf.createEntityManager();
+ em.getTransaction().begin();
+ assertClausePresentInSQL("FOR UPDATE",
+
em.createNamedQuery("findEmployeeByIdWithLock").setParameter("id", 0));
+ em.getTransaction().rollback();
+ }
+
+ public void testNamedQueryWithLockModeMustExecuteInTransaction() {
+ EntityManager em = emf.createEntityManager();
+ // execute without a transaction
+ try {
+ em.createNamedQuery("findEmployeeByIdWithLock").setParameter("id",
0).getResultList();
+ fail("Expected " + TransactionRequiredException.class.getName());
+ } catch (TransactionRequiredException e) {
+ // Expected
+ }
+ }
+
+ public void testForUpdateClauseAbsentInQueryWithDefault() {
+ EntityManager em = emf.createEntityManager();
+ assertClauseAbsentInSQL("FOR UPDATE",
+
em.createNamedQuery("findEmployeeById").setParameter("id", 0));
+ }
+
+ public void testForUpdateClauseAbsentInQueryWithExplictNoLock() {
+ EntityManager em = emf.createEntityManager();
+ assertClauseAbsentInSQL("FOR UPDATE",
+
em.createNamedQuery("findEmployeeByIdWithNoLock").setParameter("id", 0));
+ }
+
+ String getLastSQL() {
+ String last = sql.get(getSQLCount()-1);
+ assertNotNull("No last sql found", last);
+ return last;
+ }
+
+ void assertClausePresentInSQL(String clause, Query q) {
+ q.getResultList();
+ String last = getLastSQL();
+ assertTrue(clause + " is not present in " + last,
last.toUpperCase().indexOf(clause) != -1);
+ }
+
+ void assertClauseAbsentInSQL(String clause, Query q) {
+ q.getResultList();
+ String last = getLastSQL();
+ assertTrue(clause + " is not absent in " + last,
last.toUpperCase().indexOf(clause) == -1);
+ }
+}
Propchange:
openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/TestNamedQueryLockMode.java
------------------------------------------------------------------------------
svn:eol-style = native
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=930049&r1=930048&r2=930049&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
Thu Apr 1 17:23:46 2010
@@ -85,6 +85,7 @@ import org.apache.openjpa.persistence.va
import org.apache.openjpa.util.ExceptionInfo;
import org.apache.openjpa.util.Exceptions;
import org.apache.openjpa.util.ImplHelper;
+import org.apache.openjpa.util.NoTransactionException;
import org.apache.openjpa.util.RuntimeExceptionTranslator;
import org.apache.openjpa.util.UserException;
@@ -1023,7 +1024,13 @@ public class EntityManagerImpl
if (pq != null) {
pq.setInto(del);
} else {
- meta.setInto(del);
+ try {
+ meta.setInto(del);
+ } catch (NoTransactionException e) {
+ throw new
TransactionRequiredException(_loc.get("named-query-no-txn", name,
+ meta.getDefiningType(),
MixedLockLevelsHelper.fromLockLevel(meta.getLockMode())),
+ new Throwable[]{e}, name, false);
+ }
del.compile();
}
Modified:
openjpa/trunk/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties?rev=930049&r1=930048&r2=930049&view=diff
==============================================================================
---
openjpa/trunk/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties
(original)
+++
openjpa/trunk/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties
Thu Apr 1 17:23:46 2010
@@ -229,4 +229,7 @@ create-emf-depend-error: Failed to creat
invalid-version-attribute: Persistence version attribute value "{0}" is not
valid. Using version "{1}" by default.
not-jpql-or-criteria-query: Query is neither a JPQL SELECT nor a Criteria API
query.
cache-retrieve-override: The setting of CacheRetrieveMode.USE is ignored and
set to BYPASS for refresh operation.
-null-detach: Can not detach null entity
\ No newline at end of file
+null-detach: Can not detach null entity
+named-query-no-txn: Named query "{0}" declared in "{1}" specifies "{2}" lock
mode and hence must be \
+ created and executed within an active transaction.
+
\ No newline at end of file