/*
 * 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 jakarta.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 {

    @Override
    public void setUp() {
        setSupportedDatabases(
                org.apache.openjpa.jdbc.sql.DerbyDictionary.class,
                org.apache.openjpa.jdbc.sql.OracleDictionary.class,
                org.apache.openjpa.jdbc.sql.DB2Dictionary.class);
        if (isTestsDisabled()) {
            return;
        }

        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() {
                    @Override
                    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);
                        }
                    }

                    @Override
                    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);
                        }
                    }

                    @Override
                    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);
                        }
                    }

                    @Override
                    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);
                        }
                    }

                    @Override
                    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);
                        }
                    }

                    @Override
                    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() {
                    @Override
                    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 + Any + 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);
                        }
                    }

                    @Override
                    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 + Any + table2Name + Where + ForUpdate);
                            break;
                        case derby:
                            // 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.id FROM LSESecTblDtl 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 + NoJoin + Any + table1Name + Any + NoJoin + Where + ForUpdate,
                                    Select + NoJoin + Any + table2Name + Any + NoJoin + Where + ForUpdate);
                            break;
                        default:
                            assertLockTestSQLs(Select + joinTables + Where + ForUpdate);
                        }
                    }

                    @Override
                    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 + Any + table2Name + Where + ForUpdate);
                            break;
                        case derby:
                            // 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.id FROM LSESecTblDtl 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 + NoJoin + Any + table1Name + Any + NoJoin + Where + ForUpdate,
                                    Select + NoJoin + Any + table2Name + Any + NoJoin + Where + ForUpdate);
                            break;
                        default:
                            assertLockTestSQLs(Select + joinTables + Where + ForUpdate);
                        }
                    }

                    @Override
                    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 + Any + 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);
                        }
                    }

                    @Override
                    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 + Any + table2Name + Where + ForUpdate);
                            break;
                        case derby:
                            // 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.id FROM LSESecTblDtl 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 + NoJoin + Any + table1Name + Any + NoJoin + Where + ForUpdate,
                                    Select + NoJoin + Any + table2Name + Any + NoJoin + Where + ForUpdate);
                            break;
                        default:
                            assertLockTestSQLs(Select + joinTables + Where + ForUpdate);
                        }
                    }

                    @Override
                    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 + Any + 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() {

                    @Override
                    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);
                        }
                    }

                    @Override
                    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);
                        }
                    }

                    @Override
                    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);
                        }
                    }

                    @Override
                    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]
