You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by al...@apache.org on 2009/10/30 05:09:08 UTC
svn commit: r831194 [4/4] - in /openjpa/trunk:
openjpa-kernel/src/main/java/org/apache/openjpa/kernel/
openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/
openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lock/
openjpa-p...
Added: openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lock/extended/TestBasicLockScope.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lock/extended/TestBasicLockScope.java?rev=831194&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lock/extended/TestBasicLockScope.java (added)
+++ openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lock/extended/TestBasicLockScope.java Fri Oct 30 04:09:05 2009
@@ -0,0 +1,1225 @@
+/*
+ * 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.lock.extended;
+
+import javax.persistence.EntityManager;
+
+/**
+ * LockScopeTestCase subclass to test entities:
+ * - with Basic attributes
+ * - uses secondary table
+ * - uses inheritance in single table
+ * - uses inheritance and join table
+ * - uses element collection - lazy fetch (default)
+ * - uses element collection - eager fetch
+ */
+public class TestBasicLockScope extends LockScopeTestCase {
+
+ public void setUp() {
+ setUp(LSEBase.class
+ , LSESecTbl.class
+ , LSESngTblCon.class
+ , LSESngTblAbs.class
+ , LSEJoinCon.class
+ , LSEJoinAbs.class
+ , LSEEleCol.class
+ , LSEEleColEgr.class
+ , "openjpa.LockManager", "mixed",
+ "openjpa.jdbc.SynchronizeMappings", "buildSchema(ForeignKeys=true)"
+ );
+ commonSetUp(LSEBase.class
+ , LSESecTbl.class
+ , LSESngTblCon.class
+ , LSESngTblAbs.class
+ , LSEJoinCon.class
+ , LSEJoinAbs.class
+ , LSEEleCol.class
+ , LSEEleColEgr.class
+ );
+ }
+
+ public void testNormalBasicLock() {
+ commonBasicLock("testNormalBasicLock", 000, false);
+ }
+
+ public void testExtendedBasicLock() {
+ commonBasicLock("testExtendedBasicLock", 010, true);
+ }
+
+ private void commonBasicLock(String testName, int id0, boolean extended) {
+ final String tableName = "LSEBase";
+ getLog().info("** " + testName + "()");
+ String scope = extended ? "Extended" : "Normal";
+ int id1 = id0 + 1;
+
+ // create test entity.
+ LSEBase e0 = new LSEBase();
+ e0.setId(id0);
+ e0.setFirstName("firstName " + id0);
+ e0.setLastName("lastName " + id0);
+ LSEBase e1 = new LSEBase();
+ e1.setId(id1);
+ e1.setFirstName("firstName " + id1);
+ e1.setLastName("lastName " + id1);
+
+ EntityManager em = null;
+ try {
+ em = emf.createEntityManager();
+ em.getTransaction().begin();
+ em.persist(e0);
+ em.persist(e1);
+ em.getTransaction().commit();
+ } finally {
+ em = null;
+ e0 = e1 = null;
+ if (em != null && em.isOpen()) {
+ em.close();
+ }
+ }
+
+ commonLockTest(testName, LSEBase.class, id0, extended,
+ "SELECT c FROM LSEBase c WHERE c.firstName LIKE :firstName", "findLSEBase" + scope,
+ new AssertCallback() {
+ public void findNoLockDbSQL(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2:
+ // SELECT t0.version, t0.firstName, t0.lastName FROM LSEBase t0 WHERE t0.id = ?
+ // optimize for 1 row [params=(int) 0]
+ assertLockTestSQLs(Select + tableName + Where + NoDB2Lock);
+ break;
+ case derby:
+ // SELECT t0.version, t0.firstName, t0.lastName FROM LSEBase t0 WHERE t0.id = ?
+ // [params=(int) 0]
+ case oracle:
+ // SELECT t0.version, t0.firstName, t0.lastName FROM LSEBase t0 WHERE t0.id = ?
+ // [params=(int) 0]
+ default:
+ assertLockTestSQLs(Select + tableName + Where + NoForUpdate);
+ }
+ }
+
+ public void findPessimisticForcIncDbSQL(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2:
+ // SELECT t0.version, t0.firstName, t0.lastName FROM LSEBase t0 WHERE t0.id = ?
+ // optimize for 1 row FOR READ ONLY WITH RR USE AND KEEP UPDATE LOCKS [params=(int) 1]
+ // SELECT t0.version FROM LSEBase t0 WHERE t0.id = ?
+ // FOR READ ONLY WITH RR USE AND KEEP UPDATE LOCKS [params=(int) 1]
+ assertLockTestSQLs(Select + tableName + Where + DB2Lock);
+ break;
+ case derby:
+ // SELECT t0.version, t0.firstName, t0.lastName FROM
+ // LSEBase t0 WHERE t0.id = ? FOR UPDATE WITH RR [params=(int) 1]
+ case oracle:
+ // SELECT t0.version, t0.firstName, t0.lastName FROM LSEBase t0 WHERE t0.id = ? FOR UPDATE
+ // [params=(int) 1]
+ // SELECT t0.version FROM LSEBase t0 WHERE t0.id = ? FOR UPDATE [params=(int) 1]
+ default:
+ assertLockTestSQLs(Select + tableName + Where + ForUpdate);
+ }
+ }
+
+ public void queryPessimisticReadDbSQL(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2:
+ // SELECT t0.id, t0.version, t0.firstName, t0.lastName FROM LSEBase t0
+ // WHERE (t0.firstName LIKE ? ESCAPE '\')
+ // FOR READ ONLY WITH RS USE AND KEEP UPDATE LOCKS [params=(String) firstName%0]
+ // SELECT t0.version FROM LSEBase t0 WHERE t0.id = ? [params=(int) 0]
+ assertLockTestSQLs(Select + tableName + Where + DB2Lock);
+ break;
+ case derby:
+ // SELECT t0.id, t0.version, t0.firstName, t0.lastName FROM LSEBase t0 WHERE (t0.firstName
+ // LIKE ? ESCAPE '\') FOR UPDATE WITH RR [params=(String) firstName%0]
+ case oracle:
+ // SELECT t0.id, t0.version, t0.firstName, t0.lastName FROM LSEBase t0
+ // WHERE (t0.firstName LIKE ?) FOR UPDATE [params=(String) firstName%0]
+ // SELECT t0.version FROM LSEBase t0 WHERE t0.id = ? [params=(int) 0]
+ default:
+ assertLockTestSQLs(Select + tableName + Where + ForUpdate);
+ }
+ }
+
+ public void findNoLockAfterQueryPessimisticReadDbSQL(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2:
+ // SELECT t0.version, t0.firstName, t0.lastName FROM LSEBase t0 WHERE t0.id = ?
+ // optimize for 1 row [params=(int) 1]
+ assertLockTestSQLs(Select + tableName + Where + NoDB2Lock);
+ break;
+ case derby:
+ // SELECT t0.version, t0.firstName, t0.lastName FROM LSEBase t0 WHERE t0.id = ?
+ // [params=(int) 1]
+ case oracle:
+ // SELECT t0.version, t0.firstName, t0.lastName FROM LSEBase t0 WHERE t0.id = ?
+ // [params=(int) 1]
+ default:
+ assertLockTestSQLs(Select + tableName + Where + NoForUpdate);
+ }
+ }
+
+ public void namedQueryPessimisticWriteDbSql(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2:
+ // SELECT t0.id, t0.version, t0.firstName, t0.lastName FROM LSEBase t0
+ // WHERE (t0.firstName LIKE ? ESCAPE '\')
+ // FOR READ ONLY WITH RR USE AND KEEP UPDATE LOCKS [params=(String) firstName%0]
+ // SELECT t0.version FROM LSEBase t0 WHERE t0.id = ? [params=(int) 0]
+ assertLockTestSQLs(Select + tableName + Where + DB2Lock);
+ break;
+ case derby:
+ // SELECT t0.id, t0.version, t0.firstName, t0.lastName FROM LSEBase t0
+ // WHERE (t0.firstName LIKE ? ESCAPE '\') FOR UPDATE WITH RR
+ case oracle:
+ // SELECT t0.id, t0.version, t0.firstName, t0.lastName FROM LSEBase t0
+ // WHERE (t0.firstName LIKE ?) FOR UPDATE [params=(String) firstName%0]
+ // SELECT t0.version FROM LSEBase t0 WHERE t0.id = ? [params=(int) 0]
+ default:
+ assertLockTestSQLs(Select + tableName + Where + ForUpdate);
+ }
+ }
+
+ public void findNoLockAfterNamedQueryPessimisticWriteDbSql(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2:
+ // SELECT t0.version, t0.firstName, t0.lastName FROM LSEBase t0 WHERE t0.id = ?
+ // optimize for 1 row [params=(int) 1]
+ assertLockTestSQLs(Select + tableName + Where + NoDB2Lock);
+ break;
+ case derby:
+ // SELECT t0.version, t0.firstName, t0.lastName FROM LSEBase t0 WHERE t0.id = ?
+ case oracle:
+ // SELECT t0.version, t0.firstName, t0.lastName FROM LSEBase t0 WHERE t0.id = ?
+ // [params=(int) 1]
+ default:
+ assertLockTestSQLs(Select + tableName + Where + NoForUpdate);
+ }
+ }
+ });
+ }
+
+ public void testNormalSecTableLock() {
+ commonSecTableLock("testNormalSecTableLock", 100, false);
+ }
+
+ public void testExtendedSecTableLock() {
+ commonSecTableLock("testExtendedSecTableLock", 110, true);
+ }
+
+ private void commonSecTableLock(String testName, int id0, boolean extended) {
+ final String table1Name = "LSESecTbl";
+ final String table2Name = "LSESecTblDtl";
+ final String joinTables = table1Name + ".*JOIN.*" + table2Name;
+ getLog().info("** " + testName + "()");
+ String scope = extended ? "Extended" : "Normal";
+ int id1 = id0 + 1;
+
+ // create test entity.
+ LSESecTbl e0 = new LSESecTbl();
+ e0.setId(id0);
+ e0.setFirstName("firstName " + id0);
+ e0.setLastName("lastName " + id0);
+ LSESecTbl e1 = new LSESecTbl();
+ e1.setId(id1);
+ e1.setFirstName("firstName " + id1);
+ e1.setLastName("lastName " + id1);
+
+ EntityManager em = null;
+ try {
+ em = emf.createEntityManager();
+ em.getTransaction().begin();
+ em.persist(e0);
+ em.persist(e1);
+ em.getTransaction().commit();
+ } finally {
+ em = null;
+ e0 = e1 = null;
+ if (em != null && em.isOpen()) {
+ em.close();
+ }
+ }
+
+ commonLockTest(testName, LSESecTbl.class, id0, extended,
+ "SELECT c FROM LSESecTbl c WHERE c.firstName LIKE :firstName", "findLSESecTbl" + scope,
+ new AssertCallback() {
+ public void findNoLockDbSQL(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2:
+ // SELECT t0.version, t0.firstName, t1.lastName FROM LSESecTbl t0
+ // INNER JOIN LSESecTblDtl t1 ON t0.id = t1.LSESECTBL_ID WHERE t0.id = ?
+ // optimize for 1 row [params=(int) 100]
+ assertLockTestSQLs(Select + joinTables + Where + NoDB2Lock);
+ break;
+ case oracle:
+ // SELECT t0.version, t0.firstName, t1.lastName FROM LSESecTbl t0, LSESecTblDtl t1
+ // WHERE t0.id = ? AND t0.id = t1.LSESECTBL_ID [params=(int) 100]
+ assertLockTestSQLs(Select + table1Name + ".*" + table2Name + Where + NoForUpdate);
+ break;
+ case derby:
+ // SELECT t0.version, t0.firstName, t1.lastName FROM LSESecTbl t0
+ // INNER JOIN LSESecTblDtl t1 ON t0.id = t1.LSESECTBL_ID WHERE t0.id = ?
+ // [params=(int) 100]
+ default:
+ assertLockTestSQLs(Select + joinTables + Where + NoForUpdate);
+ }
+ }
+
+ public void findPessimisticForcIncDbSQL(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2:
+ // SELECT t0.version, t0.firstName, t1.lastName FROM LSESecTbl t0
+ // INNER JOIN LSESecTblDtl t1 ON t0.id = t1.LSESECTBL_ID WHERE t0.id = ?
+ // optimize for 1 row FOR READ ONLY WITH RR USE AND KEEP UPDATE LOCKS [params=(int) 101]
+ // SELECT t0.version FROM LSESecTbl t0 WHERE t0.id = ?
+ // FOR READ ONLY WITH RR USE AND KEEP UPDATE LOCKS [params=(int) 101]
+ assertLockTestSQLs(Select + joinTables + Where + DB2Lock);
+ break;
+ case oracle:
+ // SELECT t0.version, t0.firstName, t1.lastName FROM LSESecTbl t0, LSESecTblDtl t1
+ // WHERE t0.id = ? AND t0.id = t1.LSESECTBL_ID FOR UPDATE [params=(int) 101]
+ // SELECT t0.version FROM LSESecTbl t0 WHERE t0.id = ? FOR UPDATE [params=(int) 101]
+ assertLockTestSQLs(Select + table1Name + ".*" + table2Name + Where + ForUpdate);
+ break;
+ case derby: //TODO: **Non-atomic lock, SecTblDtl NOT locked *********
+ // The database is unable to lock this query. Each object matching the query will be
+ // locked individually after it is loaded; however, it is technically possible that
+ // another transaction could modify the data before the lock is obtained.
+ // SELECT t0.version, t0.firstName, t1.lastName FROM LSESecTbl t0
+ // INNER JOIN LSESecTblDtl t1 ON t0.id = t1.LSESECTBL_ID WHERE t0.id = ?
+ // [params=(int) 101]
+ // SELECT t0.id FROM LSESecTbl t0 WHERE t0.id = ? FOR UPDATE WITH RR [params=(int) 101]
+ // SELECT t0.version FROM LSESecTbl t0 WHERE t0.id = ? FOR UPDATE WITH RR [params=(int) 101]
+ assertLockTestSQLs(Select + joinTables + Where + NoForUpdate,
+ Select + table1Name + ".*" + Where + ForUpdate);
+ break;
+ default:
+ assertLockTestSQLs(Select + joinTables + Where + ForUpdate);
+ }
+ }
+
+ public void queryPessimisticReadDbSQL(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2:
+ // SELECT t0.id, t0.version, t0.firstName, t1.lastName FROM LSESecTbl t0
+ // INNER JOIN LSESecTblDtl t1 ON t0.id = t1.LSESECTBL_ID
+ // WHERE (t0.firstName LIKE ? ESCAPE '\')
+ // FOR READ ONLY WITH RS USE AND KEEP UPDATE LOCKS [params=(String) firstName%100]
+ // SELECT t0.version FROM LSESecTbl t0 WHERE t0.id = ? [params=(int) 100]
+ assertLockTestSQLs(Select + joinTables + Where + DB2Lock);
+ break;
+ case oracle:
+ // SELECT t0.id, t0.version, t0.firstName, t1.lastName FROM LSESecTbl t0, LSESecTblDtl t1
+ // WHERE (t0.firstName LIKE ?) AND t0.id = t1.LSESECTBL_ID FOR UPDATE
+ // [params=(String) firstName%100]
+ // SELECT t0.version FROM LSESecTbl t0 WHERE t0.id = ? [params=(int) 100]
+ assertLockTestSQLs(Select + table1Name + ".*" + table2Name + Where + ForUpdate);
+ break;
+ case derby: //TODO: **Non-atomic lock, SecTblDtl NOT locked *********
+ // The database is unable to lock this query. Each object matching the query will be
+ // locked individually after it is loaded; however, it is technically possible that
+ // another transaction could modify the data before the lock is obtained.
+ // SELECT t0.id, t0.version, t0.firstName, t1.lastName FROM LSESecTbl t0
+ // INNER JOIN LSESecTblDtl t1 ON t0.id = t1.LSESECTBL_ID
+ // WHERE (t0.firstName LIKE ? ESCAPE '\') [params=(String) firstName%100]
+ // SELECT t0.id FROM LSESecTbl t0 WHERE t0.id = ? FOR UPDATE WITH RR [params=(int) 100]
+ // SELECT t0.version FROM LSESecTbl t0 WHERE t0.id = ? [params=(int) 100]
+ assertLockTestSQLs(Select + joinTables + Where + NoForUpdate,
+ Select + table1Name + ".*" + Where + ForUpdate);
+ break;
+ default:
+ assertLockTestSQLs(Select + joinTables + Where + ForUpdate);
+ }
+ }
+
+ public void findNoLockAfterQueryPessimisticReadDbSQL(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2:
+ // SELECT t0.version, t0.firstName, t1.lastName FROM LSESecTbl t0
+ // INNER JOIN LSESecTblDtl t1 ON t0.id = t1.LSESECTBL_ID WHERE t0.id = ?
+ // optimize for 1 row [params=(int) 101]
+ assertLockTestSQLs(Select + joinTables + Where + NoDB2Lock);
+ break;
+ case oracle:
+ // SELECT t0.version, t0.firstName, t1.lastName FROM LSESecTbl t0, LSESecTblDtl t1
+ // WHERE t0.id = ? AND t0.id = t1.LSESECTBL_ID [params=(int) 101]
+ assertLockTestSQLs(Select + table1Name + ".*" + table2Name + Where + NoForUpdate);
+ break;
+ case derby:
+ // SELECT t0.version, t0.firstName, t1.lastName FROM LSESecTbl t0
+ // INNER JOIN LSESecTblDtl t1 ON t0.id = t1.LSESECTBL_ID WHERE t0.id = ?
+ // [params=(int) 101]
+ default:
+ assertLockTestSQLs(Select + joinTables + Where + NoForUpdate);
+ }
+ }
+
+ public void namedQueryPessimisticWriteDbSql(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2:
+ // SELECT t0.id, t0.version, t0.firstName, t1.lastName FROM LSESecTbl t0
+ // INNER JOIN LSESecTblDtl t1 ON t0.id = t1.LSESECTBL_ID
+ // WHERE (t0.firstName LIKE ? ESCAPE '\')
+ // FOR READ ONLY WITH RR USE AND KEEP UPDATE LOCKS [params=(String) firstName%100]
+ // SELECT t0.version FROM LSESecTbl t0 WHERE t0.id = ? [params=(int) 100]
+ assertLockTestSQLs(Select + joinTables + Where + DB2Lock);
+ break;
+ case oracle:
+ // SELECT t0.id, t0.version, t0.firstName, t1.lastName FROM LSESecTbl t0, LSESecTblDtl t1
+ // WHERE (t0.firstName LIKE ?) AND t0.id = t1.LSESECTBL_ID FOR UPDATE
+ // [params=(String) firstName%100]
+ // SELECT t0.version FROM LSESecTbl t0 WHERE t0.id = ? [params=(int) 100]
+ assertLockTestSQLs(Select + table1Name + ".*" + table2Name + Where + ForUpdate);
+ break;
+ case derby: //TODO: **Non-atomic lock, SecTblDtl NOT locked *********
+ // The database is unable to lock this query. Each object matching the query will be
+ // locked individually after it is loaded; however, it is technically possible that
+ // another transaction could modify the data before the lock is obtained.
+ // SELECT t0.id, t0.version, t0.firstName, t1.lastName FROM LSESecTbl t0
+ // INNER JOIN LSESecTblDtl t1 ON t0.id = t1.LSESECTBL_ID
+ // WHERE (t0.firstName LIKE ? ESCAPE '\') [params=(String) firstName%100]
+ // SELECT t0.id FROM LSESecTbl t0 WHERE t0.id = ? FOR UPDATE WITH RR [params=(int) 100]
+ // SELECT t0.version FROM LSESecTbl t0 WHERE t0.id = ? [params=(int) 100]
+ assertLockTestSQLs(Select + joinTables + Where + NoForUpdate,
+ Select + table1Name + ".*" + Where + ForUpdate);
+ break;
+ default:
+ assertLockTestSQLs(Select + joinTables + Where + ForUpdate);
+ }
+ }
+
+ public void findNoLockAfterNamedQueryPessimisticWriteDbSql(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2:
+ // SELECT t0.version, t0.firstName, t1.lastName FROM LSESecTbl t0
+ // INNER JOIN LSESecTblDtl t1 ON t0.id = t1.LSESECTBL_ID WHERE t0.id = ?
+ // optimize for 1 row [params=(int) 101]
+ assertLockTestSQLs(Select + joinTables + Where + NoDB2Lock);
+ break;
+ case oracle:
+ // SELECT t0.version, t0.firstName, t1.lastName FROM LSESecTbl t0, LSESecTblDtl t1
+ // WHERE t0.id = ? AND t0.id = t1.LSESECTBL_ID [params=(int) 101]
+ assertLockTestSQLs(Select + table1Name + ".*" + table2Name + Where + NoForUpdate);
+ break;
+ case derby:
+ // SELECT t0.version, t0.firstName, t1.lastName FROM LSESecTbl t0
+ // INNER JOIN LSESecTblDtl t1 ON t0.id = t1.LSESECTBL_ID WHERE t0.id = ?
+ // [params=(int) 101]
+ default:
+ assertLockTestSQLs(Select + joinTables + Where + NoForUpdate);
+ }
+ }
+ });
+ }
+
+ public void testNormalSingleTableLock() {
+ commonSingleTableLock("testNormalSingleTableLock", 200, false);
+ }
+
+ public void testExtendedlSingleTableLock() {
+ commonSingleTableLock("testExtendedlSingleTableLock", 210, true);
+ }
+
+ private void commonSingleTableLock(String testName, int id0, boolean extended) {
+ final String tableName = "LSESngTblAbs";
+ getLog().info("** " + testName + "()");
+ String scope = extended ? "Extended" : "Normal";
+ int id1 = id0 + 1;
+
+ // create test entity.
+ LSESngTblCon e0 = new LSESngTblCon();
+ e0.setId(id0);
+ e0.setFirstName("firstName " + id0);
+ e0.setLastName("lastName " + id0);
+ LSESngTblCon e1 = new LSESngTblCon();
+ e1.setId(id1);
+ e1.setFirstName("firstName " + id1);
+ e1.setLastName("lastName " + id1);
+
+ EntityManager em = null;
+ try {
+ em = emf.createEntityManager();
+ em.getTransaction().begin();
+ em.persist(e0);
+ em.persist(e1);
+ em.getTransaction().commit();
+ } finally {
+ em = null;
+ e0 = e1 = null;
+ if (em != null && em.isOpen()) {
+ em.close();
+ }
+ }
+
+ commonLockTest(testName, LSESngTblCon.class, id0, extended,
+ "SELECT c FROM LSESngTblAbs c WHERE c.firstName LIKE :firstName",
+ "findLSESngTblCon" + scope, new AssertCallback() {
+
+ public void findNoLockDbSQL(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2:
+ // SELECT t0.DTYPE, t0.version, t0.firstName, t0.lastName FROM LSESngTblAbs t0
+ // WHERE t0.DTYPE = ? AND t0.id = ?
+ // optimize for 1 row [params=(String) LSESngTblCon, (int) 200]
+ assertLockTestSQLs(Select + tableName + Where + NoDB2Lock);
+ break;
+ case derby:
+ // SELECT t0.DTYPE, t0.version, t0.firstName, t0.lastName FROM LSESngTblAbs t0
+ // WHERE t0.DTYPE = ? AND t0.id = ? [params=(String) LSESngTblCon, (int) 200]
+ case oracle:
+ // SELECT t0.DTYPE, t0.version, t0.firstName, t0.lastName FROM LSESngTblAbs t0
+ // WHERE t0.DTYPE = ? AND t0.id = ? [params=(String) LSESngTblCon, (int) 200]
+ default:
+ assertLockTestSQLs(Select + tableName + Where + NoForUpdate);
+ }
+ }
+
+ public void findPessimisticForcIncDbSQL(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2:
+ // SELECT t0.DTYPE, t0.version, t0.firstName, t0.lastName FROM LSESngTblAbs t0
+ // WHERE t0.DTYPE = ? AND t0.id = ?
+ // optimize for 1 row FOR READ ONLY WITH RR USE AND KEEP UPDATE LOCKS
+ // [params=(String) LSESngTblCon, (int) 201]
+ // SELECT t0.version FROM LSESngTblAbs t0 WHERE t0.id = ?
+ // FOR READ ONLY WITH RR USE AND KEEP UPDATE LOCKS [params=(int) 201]
+ assertLockTestSQLs(Select + tableName + Where + DB2Lock);
+ break;
+ case derby:
+ // SELECT t0.DTYPE, t0.version, t0.firstName, t0.lastName FROM LSESngTblAbs t0
+ // WHERE t0.DTYPE = ? AND t0.id = ? FOR UPDATE WITH RR
+ // [params=(String) LSESngTblCon, (int) 201]
+ // SELECT t0.version FROM LSESngTblAbs t0 WHERE t0.id = ? FOR UPDATE WITH RR
+ // [params=(int) 201]
+ case oracle:
+ // SELECT t0.DTYPE, t0.version, t0.firstName, t0.lastName FROM LSESngTblAbs t0
+ // WHERE t0.DTYPE = ? AND t0.id = ? FOR UPDATE
+ // [params=(String) LSESngTblCon, (int) 201]
+ // SELECT t0.version FROM LSESngTblAbs t0 WHERE t0.id = ? FOR UPDATE [params=(int) 201]
+ default:
+ assertLockTestSQLs(Select + tableName + Where + ForUpdate);
+ }
+ }
+
+ public void queryPessimisticReadDbSQL(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2:
+ // SELECT t0.id, t0.DTYPE, t0.version, t0.firstName, t0.lastName FROM LSESngTblAbs t0
+ // WHERE (t0.firstName LIKE ? ESCAPE '\')
+ // FOR READ ONLY WITH RS USE AND KEEP UPDATE LOCKS [params=(String) firstName%200]
+ // SELECT t0.version FROM LSESngTblAbs t0 WHERE t0.id = ? [params=(int) 200]
+ assertLockTestSQLs(Select + tableName + Where + DB2Lock);
+ break;
+ case derby:
+ // SELECT t0.id, t0.DTYPE, t0.version, t0.firstName, t0.lastName FROM LSESngTblAbs t0
+ // WHERE (t0.firstName LIKE ? ESCAPE '\') FOR UPDATE WITH RR
+ // [params=(String) firstName%200]
+ // SELECT t0.version FROM LSESngTblAbs t0 WHERE t0.id = ? [params=(int) 200]
+ case oracle:
+ // SELECT t0.id, t0.DTYPE, t0.version, t0.firstName, t0.lastName FROM LSESngTblAbs t0
+ // WHERE (t0.firstName LIKE ?) FOR UPDATE [params=(String) firstName%200]
+ // SELECT t0.version FROM LSESngTblAbs t0 WHERE t0.id = ? [params=(int) 200]
+ default:
+ assertLockTestSQLs(Select + tableName + Where + ForUpdate);
+ }
+ }
+
+ public void findNoLockAfterQueryPessimisticReadDbSQL(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2:
+ // SELECT t0.DTYPE, t0.version, t0.firstName, t0.lastName FROM LSESngTblAbs t0
+ // WHERE t0.DTYPE = ? AND t0.id = ?
+ // optimize for 1 row [params=(String) LSESngTblCon, (int) 201]
+ assertLockTestSQLs(Select + tableName + Where + NoDB2Lock);
+ break;
+ case derby:
+ // SELECT t0.DTYPE, t0.version, t0.firstName, t0.lastName FROM LSESngTblAbs t0
+ // WHERE t0.DTYPE = ? AND t0.id = ? [params=(String) LSESngTblCon, (int) 201]
+ case oracle:
+ // SELECT t0.DTYPE, t0.version, t0.firstName, t0.lastName FROM LSESngTblAbs t0
+ // WHERE t0.DTYPE = ? AND t0.id = ? [params=(String) LSESngTblCon, (int) 201]
+ default:
+ assertLockTestSQLs(Select + tableName + Where + NoForUpdate);
+ }
+ }
+
+ public void namedQueryPessimisticWriteDbSql(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2:
+ // SELECT t0.id, t0.DTYPE, t0.version, t0.firstName, t0.lastName FROM LSESngTblAbs t0
+ // WHERE (t0.firstName LIKE ? ESCAPE '\') AND t0.DTYPE = ?
+ // FOR READ ONLY WITH RR USE AND KEEP UPDATE LOCKS [params=(String) firstName%200, (String) LSESngTblCon]
+ // SELECT t0.version FROM LSESngTblAbs t0 WHERE t0.id = ? [params=(int) 200]
+ assertLockTestSQLs(Select + tableName + Where + DB2Lock);
+ break;
+ case derby:
+ // SELECT t0.id, t0.DTYPE, t0.version, t0.firstName, t0.lastName FROM LSESngTblAbs t0
+ // WHERE (t0.firstName LIKE ? ESCAPE '\') AND t0.DTYPE = ? FOR UPDATE WITH RR
+ // [params=(String) firstName%200, (String) LSESngTblCon]
+ // SELECT t0.version FROM LSESngTblAbs t0 WHERE t0.id = ? [params=(int) 200]
+ case oracle:
+ // SELECT t0.id, t0.DTYPE, t0.version, t0.firstName, t0.lastName FROM LSESngTblAbs t0
+ // WHERE (t0.firstName LIKE ?) AND t0.DTYPE = ? FOR UPDATE
+ // [params=(String) firstName%200, (String) LSESngTblCon]
+ // SELECT t0.version FROM LSESngTblAbs t0 WHERE t0.id = ? [params=(int) 200]
+ default:
+ assertLockTestSQLs(Select + tableName + Where + ForUpdate);
+ }
+ }
+
+ public void findNoLockAfterNamedQueryPessimisticWriteDbSql(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2:
+ // SELECT t0.DTYPE, t0.version, t0.firstName, t0.lastName FROM LSESngTblAbs t0
+ // WHERE t0.DTYPE = ? AND t0.id = ?
+ // optimize for 1 row [params=(String) LSESngTblCon, (int) 201]
+ assertLockTestSQLs(Select + tableName + Where + NoDB2Lock);
+ break;
+ case derby:
+ // SELECT t0.DTYPE, t0.version, t0.firstName, t0.lastName FROM LSESngTblAbs t0
+ // WHERE t0.DTYPE = ? AND t0.id = ? [params=(String) LSESngTblCon, (int) 201]
+ case oracle:
+ // SELECT t0.DTYPE, t0.version, t0.firstName, t0.lastName FROM LSESngTblAbs t0
+ // WHERE t0.DTYPE = ? AND t0.id = ? [params=(String) LSESngTblCon, (int) 201]
+ default:
+ assertLockTestSQLs(Select + tableName + Where + NoForUpdate);
+ }
+ }
+ });
+ }
+
+ public void testNormalJoinedLock() {
+ commonJoinedLock("testNormalJoinedLock", 400, false);
+ }
+
+ public void testExtendedJoinedLock() {
+ commonJoinedLock("testExtendedJoinedLock", 410, true);
+ }
+
+ private void commonJoinedLock(String testName, int id0, boolean extended) {
+ final String table1Name = "LSEJoinCon";
+ final String table2Name = "LSEJoinAbs";
+ final String joinTables = table1Name + ".*JOIN.*" + table2Name;
+ getLog().info("** " + testName + "()");
+ String scope = extended ? "Extended" : "Normal";
+ int id1 = id0 + 1;
+
+ // create test entity.
+ LSEJoinCon e0 = new LSEJoinCon();
+ e0.setId(id0);
+ e0.setFirstName("firstName " + id0);
+ e0.setLastName("lastName " + id0);
+ LSEJoinCon e1 = new LSEJoinCon();
+ e1.setId(id1);
+ e1.setFirstName("firstName " + id1);
+ e1.setLastName("lastName " + id1);
+
+ EntityManager em = null;
+ try {
+ em = emf.createEntityManager();
+ em.getTransaction().begin();
+ em.persist(e0);
+ em.persist(e1);
+ em.getTransaction().commit();
+ } finally {
+ em = null;
+ e0 = e1 = null;
+ if (em != null && em.isOpen()) {
+ em.close();
+ }
+ }
+
+ commonLockTest(testName, LSEJoinCon.class, id0, extended,
+ "SELECT c FROM LSEJoinCon c WHERE c.firstName LIKE :firstName", "findLSEJoinCon"
+ + scope, new AssertCallback() {
+
+ public void findNoLockDbSQL(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2:
+ // SELECT t0.id, t1.version, t1.firstName, t0.lastName FROM LSEJoinCon t0
+ // INNER JOIN LSEJoinAbs t1 ON t0.id = t1.id WHERE t0.id = ?
+ // optimize for 1 row [params=(int) 400]
+ assertLockTestSQLs(Select + joinTables + Where + NoDB2Lock);
+ break;
+ case oracle:
+ // SELECT t0.id, t1.version, t1.firstName, t0.lastName FROM LSEJoinCon t0, LSEJoinAbs t1
+ // WHERE t0.id = ? AND t0.id = t1.id [params=(int) 400]
+ assertLockTestSQLs(Select + table1Name + ".*" + table2Name + Where + NoForUpdate);
+ break;
+ case derby:
+ // SELECT t0.id, t1.version, t1.firstName, t0.lastName FROM LSEJoinCon t0
+ // INNER JOIN LSEJoinAbs t1 ON t0.id = t1.id WHERE t0.id = ? [params=(int) 400]
+ default:
+ assertLockTestSQLs(Select + joinTables + Where + NoForUpdate);
+ }
+ }
+
+ public void findPessimisticForcIncDbSQL(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2:
+ // SELECT t0.id, t1.version, t1.firstName, t0.lastName FROM LSEJoinCon t0
+ // INNER JOIN LSEJoinAbs t1 ON t0.id = t1.id WHERE t0.id = ?
+ // optimize for 1 row FOR READ ONLY WITH RR USE AND KEEP UPDATE LOCKS[params=(int) 401]
+ // SELECT t0.version FROM LSEJoinAbs t0 WHERE t0.id = ?
+ // FOR READ ONLY WITH RR USE AND KEEP UPDATE LOCKS [params=(int) 401]
+ assertLockTestSQLs(Select + joinTables + Where + DB2Lock);
+ break;
+ case oracle:
+ // SELECT t0.id, t1.version, t1.firstName, t0.lastName FROM LSEJoinCon t0, LSEJoinAbs t1
+ // WHERE t0.id = ? AND t0.id = t1.id FOR UPDATE [params=(int) 401]
+ // SELECT t0.version FROM LSEJoinAbs t0 WHERE t0.id = ? FOR UPDATE [params=(int) 401]
+ assertLockTestSQLs(Select + table1Name + ".*" + table2Name + Where + ForUpdate);
+ break;
+ case derby: //TODO: **Non-atomic lock, LSEJoinCon NOT locked *********
+ // The database is unable to lock this query. Each object matching the query will be
+ // locked individually after it is loaded; however, it is technically possible that
+ // another transaction could modify the data before the lock is obtained.
+ // SELECT t0.id, t1.version, t1.firstName, t0.lastName FROM LSEJoinCon t0
+ // INNER JOIN LSEJoinAbs t1 ON t0.id = t1.id WHERE t0.id = ? [params=(int) 401]
+ // SELECT t0.id FROM LSEJoinAbs t0 WHERE t0.id = ? FOR UPDATE WITH RR [params=(int) 401]
+ // SELECT t0.version FROM LSEJoinAbs t0 WHERE t0.id = ? FOR UPDATE WITH RR
+ // [params=(int) 401]
+ assertLockTestSQLs(Select + joinTables + Where + NoForUpdate,
+ Select + table2Name + ".*" + Where + ForUpdate);
+ break;
+ default:
+ assertLockTestSQLs(Select + joinTables + Where + ForUpdate);
+ }
+ }
+
+ public void queryPessimisticReadDbSQL(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2:
+ // SELECT t1.id, t0.id, t1.version, t1.firstName, t0.lastName FROM LSEJoinCon t0
+ // INNER JOIN LSEJoinAbs t1 ON t0.id = t1.id
+ // WHERE (t1.firstName LIKE ? ESCAPE '\')
+ // FOR READ ONLY WITH RS USE AND KEEP UPDATE LOCKS [params=(String) firstName%400]
+ // SELECT t0.version FROM LSEJoinAbs t0 WHERE t0.id = ? [params=(int) 400]
+ assertLockTestSQLs(Select + joinTables + Where + DB2Lock);
+ break;
+ case oracle:
+ // SELECT t1.id, t0.id, t1.version, t1.firstName, t0.lastName
+ // FROM LSEJoinCon t0, LSEJoinAbs t1 WHERE (t1.firstName LIKE ?) AND t0.id = t1.id
+ // FOR UPDATE [params=(String) firstName%400]
+ // SELECT t0.version FROM LSEJoinAbs t0 WHERE t0.id = ? [params=(int) 400]
+ assertLockTestSQLs(Select + table1Name + ".*" + table2Name + Where + ForUpdate);
+ break;
+ case derby: //TODO: **Non-atomic lock, LSEJoinCon NOT locked *********
+ // The database is unable to lock this query. Each object matching the query will be
+ // locked individually after it is loaded; however, it is technically possible that
+ // another transaction could modify the data before the lock is obtained.
+ // SELECT t1.id, t0.id, t1.version, t1.firstName, t0.lastName FROM LSEJoinCon t0
+ // INNER JOIN LSEJoinAbs t1 ON t0.id = t1.id WHERE (t1.firstName LIKE ? ESCAPE '\')
+ // [params=(String) firstName%400]
+ // SELECT t0.id FROM LSEJoinAbs t0 WHERE t0.id = ? FOR UPDATE WITH RR [params=(int) 400]
+ // SELECT t0.version FROM LSEJoinAbs t0 WHERE t0.id = ? [params=(int) 400]
+ assertLockTestSQLs(Select + joinTables + Where + NoForUpdate,
+ Select + table2Name + ".*" + Where + ForUpdate);
+ break;
+ default:
+ assertLockTestSQLs(Select + joinTables + Where + ForUpdate);
+ }
+ }
+
+ public void findNoLockAfterQueryPessimisticReadDbSQL(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2:
+ // SELECT t0.id, t1.version, t1.firstName, t0.lastName FROM LSEJoinCon t0
+ // INNER JOIN LSEJoinAbs t1 ON t0.id = t1.id WHERE t0.id = ?
+ // optimize for 1 row [params=(int) 401]
+ assertLockTestSQLs(Select + joinTables + Where + NoDB2Lock);
+ break;
+ case oracle:
+ // SELECT t0.id, t1.version, t1.firstName, t0.lastName FROM LSEJoinCon t0, LSEJoinAbs t1
+ // WHERE t0.id = ? AND t0.id = t1.id [params=(int) 401]
+ assertLockTestSQLs(Select + table1Name + ".*" + table2Name + Where + NoForUpdate);
+ break;
+ case derby:
+ // SELECT t0.id, t1.version, t1.firstName, t0.lastName FROM LSEJoinCon t0
+ // INNER JOIN LSEJoinAbs t1 ON t0.id = t1.id WHERE t0.id = ? [params=(int) 401]
+ default:
+ assertLockTestSQLs(Select + joinTables + Where + NoForUpdate);
+ }
+ }
+
+ public void namedQueryPessimisticWriteDbSql(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2:
+ // SELECT t1.id, t0.id, t1.version, t1.firstName, t0.lastName FROM LSEJoinCon t0
+ // INNER JOIN LSEJoinAbs t1 ON t0.id = t1.id
+ // WHERE (t1.firstName LIKE ? ESCAPE '\')
+ // FOR READ ONLY WITH RR USE AND KEEP UPDATE LOCKS [params=(String) firstName%400]
+ // SELECT t0.version FROM LSEJoinAbs t0 WHERE t0.id = ? [params=(int) 400]
+ assertLockTestSQLs(Select + joinTables + Where + DB2Lock);
+ break;
+ case oracle:
+ // SELECT t1.id, t0.id, t1.version, t1.firstName, t0.lastName
+ // FROM LSEJoinCon t0, LSEJoinAbs t1 WHERE (t1.firstName LIKE ?) AND t0.id = t1.id
+ // FOR UPDATE [params=(String) firstName%400]
+ // SELECT t0.version FROM LSEJoinAbs t0 WHERE t0.id = ? [params=(int) 400]
+ assertLockTestSQLs(Select + table1Name + ".*" + table2Name + Where + ForUpdate);
+ break;
+ case derby: //TODO: **Non-atomic lock, LSEJoinCon NOT locked *********
+ // The database is unable to lock this query. Each object matching the query will be
+ // locked individually after it is loaded; however, it is technically possible that
+ // another transaction could modify the data before the lock is obtained.
+ // SELECT t1.id, t0.id, t1.version, t1.firstName, t0.lastName FROM LSEJoinCon t0
+ // INNER JOIN LSEJoinAbs t1 ON t0.id = t1.id WHERE (t1.firstName LIKE ? ESCAPE '\')
+ // [params=(String) firstName%400]
+ // SELECT t0.id FROM LSEJoinAbs t0 WHERE t0.id = ? FOR UPDATE WITH RR [params=(int) 400]
+ // SELECT t0.version FROM LSEJoinAbs t0 WHERE t0.id = ? [params=(int) 400]
+ assertLockTestSQLs(Select + joinTables + Where + NoForUpdate,
+ Select + table2Name + ".*" + Where + ForUpdate);
+ break;
+ default:
+ assertLockTestSQLs(Select + joinTables + Where + ForUpdate);
+ }
+ }
+
+ public void findNoLockAfterNamedQueryPessimisticWriteDbSql(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2:
+ // SELECT t0.id, t1.version, t1.firstName, t0.lastName FROM LSEJoinCon t0
+ // INNER JOIN LSEJoinAbs t1 ON t0.id = t1.id WHERE t0.id = ?
+ // optimize for 1 row [params=(int) 401]
+ assertLockTestSQLs(Select + joinTables + Where + NoDB2Lock);
+ break;
+ case oracle:
+ // SELECT t0.id, t1.version, t1.firstName, t0.lastName FROM LSEJoinCon t0, LSEJoinAbs t1
+ // WHERE t0.id = ? AND t0.id = t1.id [params=(int) 401]
+ assertLockTestSQLs(Select + table1Name + ".*" + table2Name + Where + NoForUpdate);
+ break;
+ case derby:
+ // SELECT t0.id, t1.version, t1.firstName, t0.lastName FROM LSEJoinCon t0
+ // INNER JOIN LSEJoinAbs t1 ON t0.id = t1.id WHERE t0.id = ? [params=(int) 401]
+ default:
+ assertLockTestSQLs(Select + joinTables + Where + NoForUpdate);
+ }
+ }
+ });
+ }
+
+ public void testNormalElementCollectionLock() {
+ commonElementCollectionLock("testNormalElementCollectionLock", 500, false);
+ }
+
+ public void testExtendedElementCollectionLock() {
+ commonElementCollectionLock("testExtendedElementCollectionLock", 510, true);
+ }
+
+ private void commonElementCollectionLock(String testName, int id0, boolean extended) {
+ final String tableName ="LSEEleCol";
+ getLog().info("** " + testName + "()");
+ String scope = extended ? "Extended" : "Normal";
+ int id1 = id0 + 1;
+
+ // create test entity.
+ LSEEleCol e0 = new LSEEleCol();
+ e0.setId(id0);
+ e0.setFirstName("firstName lazy " + id0);
+ e0.addCollection(id0 + "String1");
+ e0.addCollection(id0 + "String2");
+ LSEEleCol e1 = new LSEEleCol();
+ e1.setId(id1);
+ e1.setFirstName("lazy " + id1);
+ e1.addCollection(id1 + "String1");
+ e1.addCollection(id1 + "String2");
+
+ EntityManager em = null;
+ try {
+ em = emf.createEntityManager();
+ em.getTransaction().begin();
+ em.persist(e0);
+ em.persist(e1);
+ em.getTransaction().commit();
+ } finally {
+ em = null;
+ e0 = e1 = null;
+ if (em != null && em.isOpen()) {
+ em.close();
+ }
+ }
+
+ commonLockTest(testName, LSEEleCol.class, id0, extended,
+ "SELECT c FROM LSEEleCol c WHERE c.firstName LIKE :firstName", "findLSEEleCol" + scope,
+ new AssertCallback() {
+
+ public void findNoLockDbSQL(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2:
+ // SELECT t0.version, t0.firstName FROM LSEEleCol t0 WHERE t0.id = ?
+ // optimize for 1 row [params=(int) 500]
+ assertLockTestSQLs(Select + tableName + Where + NoDB2Lock);
+ break;
+ case derby:
+ // SELECT t0.version, t0.firstName FROM LSEEleCol t0 WHERE t0.id = ? [params=(int) 500]
+ case oracle:
+ // SELECT t0.version, t0.firstName FROM LSEEleCol t0 WHERE t0.id = ? [params=(int) 500]
+ default:
+ assertLockTestSQLs(Select + tableName + Where + NoForUpdate);
+ }
+ }
+
+ public void findPessimisticForcIncDbSQL(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2:
+ // SELECT t0.version, t0.firstName FROM LSEEleCol t0 WHERE t0.id = ?
+ // optimize for 1 row FOR READ ONLY WITH RR USE AND KEEP UPDATE LOCKS
+ // [params=(int) 501]
+ // SELECT t0.version FROM LSEEleCol t0 WHERE t0.id = ?
+ // FOR READ ONLY WITH RR USE AND KEEP UPDATE LOCKS [params=(int) 501]
+ assertLockTestSQLs(Select + tableName + Where + DB2Lock);
+ break;
+ case derby:
+ // SELECT t0.version, t0.firstName FROM LSEEleCol t0 WHERE t0.id = ? FOR UPDATE WITH RR
+ // [params=(int) 501]
+ // SELECT t0.version FROM LSEEleCol t0 WHERE t0.id = ? FOR UPDATE WITH RR [params=(int) 501]
+ case oracle:
+ // SELECT t0.version, t0.firstName FROM LSEEleCol t0 WHERE t0.id = ? FOR UPDATE
+ // [params=(int) 501]
+ // SELECT t0.version FROM LSEEleCol t0 WHERE t0.id = ? FOR UPDATE [params=(int) 501]
+ default:
+ assertLockTestSQLs(Select + tableName + Where + ForUpdate);
+ }
+ }
+
+ public void queryPessimisticReadDbSQL(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2:
+ // SELECT t0.id, t0.version, t0.firstName FROM LSEEleCol t0
+ // WHERE (t0.firstName LIKE ? ESCAPE '\')
+ // FOR READ ONLY WITH RS USE AND KEEP UPDATE LOCKS [params=(String) firstName%500]
+ // SELECT t0.version FROM LSEEleCol t0 WHERE t0.id = ? [params=(int) 500]
+ assertLockTestSQLs(Select + tableName + Where + DB2Lock);
+ break;
+ case derby:
+ // SELECT t0.id, t0.version, t0.firstName FROM LSEEleCol t0 WHERE
+ // (t0.firstName LIKE ? ESCAPE '\') FOR UPDATE WITH RR [params=(String) firstName%500]
+ // SELECT t0.version FROM LSEEleCol t0 WHERE t0.id = ? [params=(int) 500]
+ case oracle:
+ // SELECT t0.id, t0.version, t0.firstName FROM LSEEleCol t0 WHERE (t0.firstName LIKE ?)
+ // FOR UPDATE [params=(String) firstName%500]
+ // SELECT t0.version FROM LSEEleCol t0 WHERE t0.id = ? [params=(int) 500]
+ default:
+ assertLockTestSQLs(Select + tableName + Where + ForUpdate);
+ }
+ }
+
+ public void findNoLockAfterQueryPessimisticReadDbSQL(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2:
+ // SELECT t0.version, t0.firstName FROM LSEEleCol t0 WHERE t0.id = ?
+ // optimize for 1 row [params=(int) 501]
+ assertLockTestSQLs(Select + tableName + Where + NoDB2Lock);
+ break;
+ case derby:
+ // SELECT t0.version, t0.firstName FROM LSEEleCol t0 WHERE t0.id = ? [params=(int) 501]
+ case oracle:
+ // SELECT t0.version, t0.firstName FROM LSEEleCol t0 WHERE t0.id = ? [params=(int) 501]
+ default:
+ assertLockTestSQLs(Select + tableName + Where + NoForUpdate);
+ }
+ }
+
+ public void namedQueryPessimisticWriteDbSql(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2:
+ // SELECT t0.id, t0.version, t0.firstName FROM LSEEleCol t0
+ // WHERE (t0.firstName LIKE ? ESCAPE '\')
+ // FOR READ ONLY WITH RR USE AND KEEP UPDATE LOCKS [params=(String) firstName%500]
+ // SELECT t0.version FROM LSEEleCol t0 WHERE t0.id = ? [params=(int) 500]
+ assertLockTestSQLs(Select + tableName + Where + DB2Lock);
+ break;
+ case derby:
+ // SELECT t0.id, t0.version, t0.firstName FROM LSEEleCol t0 WHERE
+ // (t0.firstName LIKE ? ESCAPE '\') FOR UPDATE WITH RR [params=(String) firstName%500]
+ // SELECT t0.version FROM LSEEleCol t0 WHERE t0.id = ? [params=(int) 500]
+ case oracle:
+ // SELECT t0.id, t0.version, t0.firstName FROM LSEEleCol t0 WHERE (t0.firstName LIKE ?)
+ // FOR UPDATE [params=(String) firstName%500]
+ // SELECT t0.version FROM LSEEleCol t0 WHERE t0.id = ? [params=(int) 500]
+ default:
+ assertLockTestSQLs(Select + tableName + Where + ForUpdate);
+ }
+ }
+
+ public void findNoLockAfterNamedQueryPessimisticWriteDbSql(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2:
+ // SELECT t0.version, t0.firstName FROM LSEEleCol t0 WHERE t0.id = ?
+ // optimize for 1 row [params=(int) 501]
+ assertLockTestSQLs(Select + tableName + Where + NoDB2Lock);
+ break;
+ case derby:
+ // SELECT t0.version, t0.firstName FROM LSEEleCol t0 WHERE t0.id = ? [params=(int) 501]
+ case oracle:
+ // SELECT t0.version, t0.firstName FROM LSEEleCol t0 WHERE t0.id = ? [params=(int) 501]
+ default:
+ assertLockTestSQLs(Select + tableName + Where + NoForUpdate);
+ }
+ }
+ });
+ }
+
+ public void testNormalElementCollectionEagerLock() {
+ commonElementCollectionEagerLock("testNormalElementCollectionEagerLock", 600, false);
+ }
+
+ public void testExtendedElementCollectionEagerLock() {
+ commonElementCollectionEagerLock("testExtendedElementCollectionEagerLock", 610, true);
+ }
+
+ private void commonElementCollectionEagerLock(String testName, int id0, boolean extended) {
+ final String table1Name = "LSEEleColEgr";
+ final String table2Name = "LSEEleColEgr_collection";
+// final String table2Name_oracle = table2Name;//.toUpperCase().substring(0, Math.min(table2Name.length(), 30));
+ final String joinTables = table1Name + ".*JOIN.*" + table2Name;
+ getLog().info("** " + testName + "()");
+ String scope = extended ? "Extended" : "Normal";
+ int id1 = id0 + 1;
+
+ // create test entity.
+ LSEEleColEgr e0 = new LSEEleColEgr();
+ e0.setId(id0);
+ e0.setFirstName("firstName eager " + id0);
+ e0.addCollection(id0 + "String1");
+ e0.addCollection(id0 + "String2");
+ LSEEleColEgr e1 = new LSEEleColEgr();
+ e1.setId(id1);
+ e1.setFirstName("firstName eager " + id1);
+ e1.addCollection(id1 + "String1");
+ e1.addCollection(id1 + "String2");
+
+ EntityManager em = null;
+ try {
+ em = emf.createEntityManager();
+ em.getTransaction().begin();
+ em.persist(e0);
+ em.persist(e1);
+ em.getTransaction().commit();
+ } finally {
+ em = null;
+ e0 = e1 = null;
+ if (em != null && em.isOpen()) {
+ em.close();
+ }
+ }
+
+ commonLockTest(testName, LSEEleColEgr.class, id0, extended,
+ "SELECT c FROM LSEEleColEgr c WHERE c.firstName LIKE :firstName",
+ "findLSEEleColEgr" + scope, new AssertCallback() {
+
+ public void findNoLockDbSQL(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2:
+ // SELECT t0.version, t0.firstName, t1.LSEELECOLEGR_ID, t1.element FROM LSEEleColEgr t0
+ // LEFT OUTER JOIN LSEEleColEgr_collection t1 ON t0.id = t1.LSEELECOLEGR_ID
+ // WHERE t0.id = ? [params=(int) 600]
+ assertLockTestSQLs(Select + joinTables + Where + NoDB2Lock);
+ break;
+ case oracle:
+ // SELECT t0.version, t0.firstName, t1.LSEELECOLEGR_ID, t1.element
+ // FROM LSEEleColEgr t0, LSEEleColEgr_collection t1
+ // WHERE t0.id = ? AND t0.id = t1.LSEELECOLEGR_ID(+) [params=(int) 600]
+ assertLockTestSQLs(Select + table1Name + ".*" + table2Name + Where + "\\(\\+\\).*"
+ + NoForUpdate);
+ break;
+ case derby:
+ // SELECT t0.version, t0.firstName, t1.LSEELECOLEGR_ID, t1.element FROM LSEEleColEgr t0
+ // LEFT OUTER JOIN LSEEleColEgr_collection t1 ON t0.id = t1.LSEELECOLEGR_ID
+ // WHERE t0.id = ? [params=(int) 600]
+ default:
+ assertLockTestSQLs(Select + joinTables + Where + NoForUpdate);
+ }
+ }
+
+ public void findPessimisticForcIncDbSQL(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2:
+ // SELECT t0.version, t0.firstName, t1.LSEELECOLEGR_ID, t1.element FROM LSEEleColEgr t0
+ // LEFT OUTER JOIN LSEEleColEgr_collection t1 ON t0.id = t1.LSEELECOLEGR_ID
+ // WHERE t0.id = ? FOR READ ONLY WITH RR USE AND KEEP UPDATE LOCKS [params=(int) 601]
+ // SELECT t0.version FROM LSEEleColEgr t0 WHERE t0.id = ?
+ // FOR READ ONLY WITH RR USE AND KEEP UPDATE LOCKS [params=(int) 601]
+ assertLockTestSQLs(Select + joinTables + Where + DB2Lock);
+ break;
+ case oracle:
+ // SELECT t0.version, t0.firstName, t1.LSEELECOLEGR_ID, t1.element
+ // FROM LSEEleColEgr t0, LSEEleColEgr_collection t1
+ // WHERE t0.id = ? AND t0.id = t1.LSEELECOLEGR_ID(+) FOR UPDATE [params=(int) 601]
+ // SELECT t0.version FROM LSEEleColEgr t0 WHERE t0.id = ? FOR UPDATE [params=(int) 601]
+ assertLockTestSQLs(Select + table1Name + ".*" + table2Name + Where + "\\(\\+\\).*"
+ + NoForUpdate);
+ break;
+ case derby: // **Non-atomic lock, No need to lock LSEEleColEgr_collection *********
+ // TODO: Can do the same as query below, if extended scope. i.e. select LSEEleColEgr
+ // with lock and fetch element collection without lock.
+ // The database is unable to lock this query. Each object matching the query will be
+ // locked individually after it is loaded; however, it is technically possible that
+ // another transaction could modify the data before the lock is obtained.
+ // SELECT t0.version, t0.firstName, t1.LSEELECOLEGR_ID, t1.element FROM LSEEleColEgr t0
+ // LEFT OUTER JOIN LSEEleColEgr_collection t1 ON t0.id = t1.LSEELECOLEGR_ID
+ // WHERE t0.id = ? [params=(int) 601]
+ // SELECT t0.id FROM LSEEleColEgr t0 WHERE t0.id = ? FOR UPDATE WITH RR [params=(int) 601]
+ // SELECT t0.version FROM LSEEleColEgr t0 WHERE t0.id = ? FOR UPDATE WITH RR
+ // [params=(int) 601]
+ assertLockTestSQLs(Select + joinTables + Where + NoForUpdate,
+ Select + table1Name + ".*" + Where + ForUpdate);
+ break;
+ default:
+ assertLockTestSQLs(Select + joinTables + Where + ForUpdate);
+ }
+ }
+
+ public void queryPessimisticReadDbSQL(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2: // **Non-atomic lock, No need to lock LSEEleColEgr_collection *********
+ // The database is unable to lock this query. Each object matching the query will be
+ // locked individually after it is loaded; however, it is technically possible that
+ // another transaction could modify the data before the lock is obtained.
+ // SELECT t0.id, t0.version, t0.firstName FROM LSEEleColEgr t0
+ // WHERE (t0.firstName LIKE ? ESCAPE '\')
+ // FOR READ ONLY WITH RS USE AND KEEP UPDATE LOCKS [params=(String) firstName%600]
+ // SELECT t0.id, t1.element FROM LSEEleColEgr t0 INNER JOIN LSEEleColEgr_collection t1
+ // ON t0.id = t1.LSEELECOLEGR_ID WHERE (t0.firstName LIKE ? ESCAPE '\')
+ // ORDER BY t0.id ASC [params=(String) firstName%600]
+ // SELECT t0.version FROM LSEEleColEgr t0 WHERE t0.id = ? [params=(int) 600]
+ assertLockTestSQLs(Select + "LSEEleColEgr.*" + Where + DB2Lock,
+ Select + joinTables + Where + NoDB2Lock);
+ break;
+ case oracle:
+ // SELECT t0.id, t0.version, t0.firstName FROM LSEEleColEgr t0 WHERE (t0.firstName LIKE ?)
+ // FOR UPDATE [params=(String) firstName%600]
+ // SELECT t0.id, t1.element FROM LSEEleColEgr t0, LSEEleColEgr_collection t1
+ // WHERE (t0.firstName LIKE ?) AND t0.id = t1.LSEELECOLEGR_ID ORDER BY t0.id ASC
+ // FOR UPDATE [params=(String) firstName%600]
+ // SELECT t0.version FROM LSEEleColEgr t0 WHERE t0.id = ? [params=(int) 600]
+ assertLockTestSQLs(Select + table1Name + ".*" + table2Name + Where + ForUpdate);
+ break;
+ case derby: //**Non-atomic lock, No need to lock LSEEleColEgr_Collection *********
+ // The database is unable to lock this query. Each object matching the query will be
+ // locked individually after it is loaded; however, it is technically possible that
+ // another transaction could modify the data before the lock is obtained.
+ // SELECT t0.id, t0.version, t0.firstName FROM LSEEleColEgr t0 WHERE
+ // (t0.firstName LIKE ? ESCAPE '\') FOR UPDATE WITH RR [params=(String) firstName%600]
+ // SELECT t0.id, t1.element FROM LSEEleColEgr t0 INNER JOIN LSEEleColEgr_collection t1
+ // ON t0.id = t1.LSEELECOLEGR_ID WHERE (t0.firstName LIKE ? ESCAPE '\')
+ // ORDER BY t0.id ASC [params=(String) firstName%600]
+ // SELECT t0.version FROM LSEEleColEgr t0 WHERE t0.id = ? [params=(int) 600]
+ assertLockTestSQLs(Select + joinTables + Where + NoForUpdate,
+ Select + table1Name + ".*" + Where + ForUpdate);
+ break;
+ default:
+ assertLockTestSQLs(Select + joinTables + Where + ForUpdate);
+ }
+ }
+
+ public void findNoLockAfterQueryPessimisticReadDbSQL(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2:
+ // SELECT t0.version, t0.firstName, t1.LSEELECOLEGR_ID, t1.element FROM LSEEleColEgr t0
+ // LEFT OUTER JOIN LSEEleColEgr_collection t1 ON t0.id = t1.LSEELECOLEGR_ID
+ // WHERE t0.id = ? [params=(int) 601]
+ assertLockTestSQLs(Select + "LSEEleColEgr.*" + Where + DB2Lock,
+ Select + joinTables + Where + NoDB2Lock);
+ break;
+ case oracle:
+ // SELECT t0.version, t0.firstName, t1.LSEELECOLEGR_ID, t1.element
+ // FROM LSEEleColEgr t0, LSEEleColEgr_collection t1
+ // WHERE t0.id = ? AND t0.id = t1.LSEELECOLEGR_ID(+) [params=(int) 601]
+ assertLockTestSQLs(Select + table1Name + ".*" + table2Name + Where + "\\(\\+\\).*"
+ + NoForUpdate);
+ break;
+ case derby:
+ // SELECT t0.version, t0.firstName, t1.LSEELECOLEGR_ID, t1.element FROM LSEEleColEgr t0
+ // LEFT OUTER JOIN LSEEleColEgr_collection t1 ON t0.id = t1.LSEELECOLEGR_ID
+ // WHERE t0.id = ? [params=(int) 601]
+ default:
+ assertLockTestSQLs(Select + joinTables + Where + NoForUpdate);
+ }
+ }
+
+ public void namedQueryPessimisticWriteDbSql(EntityManager em) {
+ switch (getDBType(em)) {
+ case db2: // **Non-atomic lock, No need to lock LSEEleColEgr_collection *********
+ // The database is unable to lock this query. Each object matching the query will be
+ // locked individually after it is loaded; however, it is technically possible that
+ // another transaction could modify the data before the lock is obtained.
+ // SELECT t0.id, t0.version, t0.firstName FROM LSEEleColEgr t0
+ // WHERE (t0.firstName LIKE ? ESCAPE '\')
+ // FOR READ ONLY WITH RR USE AND KEEP UPDATE LOCKS [params=(String) firstName%600]
+ // SELECT t0.id, t1.element FROM LSEEleColEgr t0 INNER JOIN LSEEleColEgr_collection t1
+ // ON t0.id = t1.LSEELECOLEGR_ID WHERE (t0.firstName LIKE ? ESCAPE '\')
+ // ORDER BY t0.id ASC [params=(String) firstName%600]
+ // SELECT t0.version FROM LSEEleColEgr t0 WHERE t0.id = ? [params=(int) 600]
+ assertLockTestSQLs(Select + "LSEEleColEgr.*" + Where + DB2Lock,
+ Select + joinTables + Where + NoDB2Lock);
+ break;
+ case oracle:
+ // SELECT t0.id, t0.version, t0.firstName FROM LSEEleColEgr t0 WHERE (t0.firstName LIKE ?)
+ // FOR UPDATE [params=(String) firstName%600]
+ // SELECT t0.id, t1.element FROM LSEEleColEgr t0, LSEEleColEgr_collection t1
+ // WHERE (t0.firstName LIKE ?) AND t0.id = t1.LSEELECOLEGR_ID ORDER BY t0.id ASC
+ // FOR UPDATE [params=(String) firstName%600]
+ // SELECT t0.version FROM LSEEleColEgr t0 WHERE t0.id = ? [params=(int) 600]
+ assertLockTestSQLs(Select + table1Name + ".*" + table2Name + Where + ForUpdate);
+ break;
+ case derby: // **Non-atomic lock, No need to lock LSEEleColEgr_collection *********
+ // The database is unable to lock this query. Each object matching the query will be
+ // locked individually after it is loaded; however, it is technically possible that
+ // another transaction could modify the data before the lock is obtained.
+ // SELECT t0.id, t0.version, t0.firstName FROM LSEEleColEgr t0 WHERE
+ // (t0.firstName LIKE ? ESCAPE '\') FOR UPDATE WITH RR [params=(String) firstName%600]
+ // SELECT t0.id, t1.element FROM LSEEleColEgr t0 INNER JOIN LSEEleColEgr_collection t1
+ // ON t0.id = t1.LSEELECOLEGR_ID WHERE (t0.firstName LIKE ? ESCAPE '\')
+ // ORDER BY t0.id ASC [params=(String) firstName%600]
+ // SELECT t0.version FROM LSEEleColEgr t0 WHERE t0.id = ? [params=(int) 600]
+ assertLockTestSQLs(Select + joinTables + Where + NoForUpdate,
+ Select + table1Name + ".*" + Where + ForUpdate);
+ break;
+ default:
+ assertLockTestSQLs(Select + joinTables + Where + ForUpdate);
+ }
+ }
+
+ public void findNoLockAfterNamedQueryPessimisticWriteDbSql(EntityManager em) {
+ switch (getDBType(em)) { // **Check
+ case db2:
+ // SELECT t0.version, t0.firstName, t1.LSEELECOLEGR_ID, t1.element FROM LSEEleColEgr t0
+ // LEFT OUTER JOIN LSEEleColEgr_collection t1 ON t0.id = t1.LSEELECOLEGR_ID
+ // WHERE t0.id = ? [params=(int) 601]
+ assertLockTestSQLs(Select + joinTables + Where + NoDB2Lock);
+ break;
+ case oracle:
+ // SELECT t0.version, t0.firstName, t1.LSEELECOLEGR_ID, t1.element
+ // FROM LSEEleColEgr t0, LSEEleColEgr_collection t1
+ // WHERE t0.id = ? AND t0.id = t1.LSEELECOLEGR_ID(+) [params=(int) 601]
+ assertLockTestSQLs(Select + table1Name + ".*" + table2Name + Where + "\\(\\+\\).*"
+ + NoForUpdate);
+ break;
+ case derby:
+ // SELECT t0.version, t0.firstName, t1.LSEELECOLEGR_ID, t1.element FROM LSEEleColEgr t0
+ // LEFT OUTER JOIN LSEEleColEgr_collection t1 ON t0.id = t1.LSEELECOLEGR_ID
+ // WHERE t0.id = ? [params=(int) 601]
+ default:
+ assertLockTestSQLs(Select + joinTables + Where + NoForUpdate);
+ }
+ }
+ });
+ }
+}
Propchange: openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lock/extended/TestBasicLockScope.java
------------------------------------------------------------------------------
svn:eol-style = native
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=831194&r1=831193&r2=831194&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 Fri Oct 30 04:09:05 2009
@@ -61,8 +61,6 @@
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
-import javax.persistence.Access;
-import javax.persistence.AccessType;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.Lob;
@@ -1772,7 +1770,9 @@
meta.setLanguage(JPQLParser.LANG_JPQL);
for (QueryHint hint : query.hints())
meta.addHint(hint.name(), hint.value());
-
+ if (query.lockMode() != null) {
+ meta.addHint("openjpa.FetchPlan.ReadLockMode", query.lockMode());
+ }
meta.setSource(getSourceFile(), (el instanceof Class) ? el : null,
SourceTracker.SRC_ANNOTATIONS);
if (isMetaDataMode())
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=831194&r1=831193&r2=831194&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 Fri Oct 30 04:09:05 2009
@@ -20,9 +20,9 @@
import java.util.Collection;
import java.util.Map;
-import java.util.Set;
import javax.persistence.LockModeType;
+import javax.persistence.PessimisticLockScope;
import org.apache.openjpa.kernel.DataCacheRetrieveMode;
import org.apache.openjpa.kernel.DataCacheStoreMode;
@@ -322,6 +322,16 @@
public FetchPlan setLockTimeout(int timeout);
/**
+ * The lock scope to use for locking loaded objects.
+ */
+ public PessimisticLockScope getLockScope();
+
+ /**
+ * The lock scope to use for locking loaded objects.
+ */
+ public FetchPlan setLockScope(PessimisticLockScope scope);
+
+ /**
* The number of milliseconds to wait for a query, or -1 for no
* limit.
*/
Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/FetchPlanHintHandler.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/FetchPlanHintHandler.java?rev=831194&r1=831193&r2=831194&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/FetchPlanHintHandler.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/FetchPlanHintHandler.java Fri Oct 30 04:09:05 2009
@@ -59,6 +59,7 @@
}
// Initialize javax.persistence to openjpa.FetchPlan hint mapping.
javaxHintsMap.put(JPAProperties.LOCK_TIMEOUT, PREFIX_FETCHPLAN + "LockTimeout");
+ javaxHintsMap.put(JPAProperties.LOCK_SCOPE, PREFIX_FETCHPLAN + "LockScope");
javaxHintsMap.put(JPAProperties.QUERY_TIMEOUT, PREFIX_FETCHPLAN + "QueryTimeout");
// Initialize hint precedence order mapping from list.
String[][] precedenceMapList = {
@@ -66,6 +67,10 @@
PREFIX_FETCHPLAN + "LockTimeout",
PREFIX_OPENJPA + "LockTimeout" },
+ { JPAProperties.LOCK_SCOPE,
+ PREFIX_FETCHPLAN + "LockScope",
+ PREFIX_OPENJPA + "LockScope" },
+
{ JPAProperties.QUERY_TIMEOUT,
PREFIX_FETCHPLAN + "QueryTimeout",
PREFIX_OPENJPA + "QueryTimeout" },
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=831194&r1=831193&r2=831194&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 Fri Oct 30 04:09:05 2009
@@ -25,6 +25,7 @@
import java.util.Map;
import javax.persistence.LockModeType;
+import javax.persistence.PessimisticLockScope;
import org.apache.openjpa.kernel.DataCacheRetrieveMode;
import org.apache.openjpa.kernel.DataCacheStoreMode;
@@ -237,6 +238,15 @@
return this;
}
+ public PessimisticLockScope getLockScope() {
+ return LockScopesHelper.fromLockScope(_fetch.getLockScope());
+ }
+
+ public FetchPlan setLockScope(PessimisticLockScope scope) {
+ _fetch.setLockScope(LockScopesHelper.toLockScope(scope));
+ return this;
+ }
+
public int getQueryTimeout() {
return _fetch.getQueryTimeout();
}
Added: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/LockScopesHelper.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/LockScopesHelper.java?rev=831194&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/LockScopesHelper.java (added)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/LockScopesHelper.java Fri Oct 30 04:09:05 2009
@@ -0,0 +1,49 @@
+/*
+ * 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;
+
+import javax.persistence.PessimisticLockScope;
+
+import org.apache.openjpa.kernel.LockScopes;
+
+/**
+ * Helper methods translate between JPA-defined pessimistic lock scope and
+ * OpenJPA internal lock scope levels.
+ *
+ * @since 2.0.0
+ */
+public class LockScopesHelper {
+ /**
+ * Translates javax.persistence LockModeType to internal lock level.
+ */
+ public static int toLockScope(PessimisticLockScope scope) {
+ if (scope == null || scope == PessimisticLockScope.NORMAL)
+ return LockScopes.LOCKSCOPE_NORMAL;
+ return LockScopes.LOCKSCOPE_EXTENDED;
+ }
+
+ /**
+ * Translates internal lock level to javax.persistence LockModeType.
+ */
+ public static PessimisticLockScope fromLockScope(int level) {
+ if (level < LockScopes.LOCKSCOPE_EXTENDED)
+ return PessimisticLockScope.NORMAL;
+ return PessimisticLockScope.EXTENDED;
+ }
+}
Propchange: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/LockScopesHelper.java
------------------------------------------------------------------------------
svn:eol-style = native
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=831194&r1=831193&r2=831194&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 Fri Oct 30 04:09:05 2009
@@ -31,15 +31,14 @@
import java.util.Map;
import java.util.Set;
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;
-import org.xml.sax.Attributes;
-import org.xml.sax.Locator;
-import org.xml.sax.SAXException;
import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.enhance.PersistenceCapable;
import org.apache.openjpa.event.BeanLifecycleCallbacks;
@@ -61,7 +60,6 @@
import org.apache.openjpa.meta.JavaTypes;
import org.apache.openjpa.meta.LifecycleMetaData;
import org.apache.openjpa.meta.MetaDataContext;
-import org.apache.openjpa.meta.MetaDataDefaults;
import org.apache.openjpa.meta.MetaDataFactory;
import static org.apache.openjpa.meta.MetaDataModes.*;
import org.apache.openjpa.meta.MetaDataRepository;
@@ -73,6 +71,9 @@
import static org.apache.openjpa.persistence.PersistenceStrategy.*;
import org.apache.openjpa.util.ImplHelper;
import org.apache.openjpa.util.MetaDataException;
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
import serp.util.Numbers;
@@ -1106,7 +1107,7 @@
throws SAXException {
FieldMetaData fmd = (FieldMetaData) currentElement();
int typeCode = fmd.isElementCollection() ? fmd.getElement().getDeclaredTypeCode() : fmd.getDeclaredTypeCode();
- Class type = fmd.isElementCollection() ? fmd.getElement().getDeclaredType() : fmd.getDeclaredType();
+ Class<?> type = fmd.isElementCollection() ? fmd.getElement().getDeclaredType() : fmd.getDeclaredType();
if (typeCode != JavaTypes.STRING
&& type != char[].class
&& type != Character[].class
@@ -1651,12 +1652,10 @@
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));
- **/
+ String lockModeStr = attrs.getValue("lock-mode");
+ if (lockModeStr != null) {
+ meta.addHint("openjpa.FetchPlan.ReadLockMode", LockModeType.valueOf(lockModeStr));
+ }
Locator locator = getLocation().getLocator();
if (locator != null) {
meta.setLineNumber(Numbers.valueOf(locator.getLineNumber()));