mirror of https://github.com/apache/openjpa.git
OPENJPA-891 - Fix non-versioned entity locking support and add tests.
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@783633 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
27b0abd46b
commit
edb329a475
|
@ -83,7 +83,7 @@ public class MixedLockManager extends PessimisticLockManager {
|
|||
ClassMapping mapping = (ClassMapping) sm.getMetaData();
|
||||
try {
|
||||
if (!mapping.getVersion().checkVersion(sm, this.getStore(),
|
||||
true)) {
|
||||
false)) {
|
||||
throw (new OptimisticException(_loc.get(
|
||||
"optimistic-violation-lock").getMessage()))
|
||||
.setFailedObject(sm.getObjectId());
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.openjpa.persistence.lockmgr;
|
||||
|
||||
import java.io.Externalizable;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.ObjectOutput;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class LockEmployeeNonVersion implements Externalizable {
|
||||
|
||||
@Id
|
||||
private int id;
|
||||
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.getClass().getName() + '@'
|
||||
+ Integer.toHexString(System.identityHashCode(this)) + "[id="
|
||||
+ getId() + "] first=" + getFirstName()
|
||||
+ ", last=" + getLastName();
|
||||
}
|
||||
|
||||
public void readExternal(ObjectInput in) throws IOException,
|
||||
ClassNotFoundException {
|
||||
id = in.readInt();
|
||||
firstName = (String) in.readObject();
|
||||
lastName = (String) in.readObject();
|
||||
}
|
||||
|
||||
public void writeExternal(ObjectOutput out) throws IOException {
|
||||
out.writeInt(id);
|
||||
out.writeObject(firstName);
|
||||
out.writeObject(lastName);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,240 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.openjpa.persistence.lockmgr;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.LockModeType;
|
||||
|
||||
import org.apache.openjpa.lib.log.Log;
|
||||
import org.apache.openjpa.persistence.test.SQLListenerTestCase;
|
||||
|
||||
/**
|
||||
* Test find, lock and refresh em methods against non-versioned entity.
|
||||
*/
|
||||
public class TestMixedLockManagerNonVersion extends SQLListenerTestCase {
|
||||
|
||||
private String empTableName;
|
||||
|
||||
public void setUp() {
|
||||
setUp(LockEmployeeNonVersion.class
|
||||
, "openjpa.LockManager", "mixed"
|
||||
, "openjpa.Optimistic", "false"
|
||||
);
|
||||
commonSetUp();
|
||||
}
|
||||
|
||||
/*
|
||||
* Test em.find(lockMode) on non-versioned entity.
|
||||
*/
|
||||
public void testFindNonVersionWithLock() {
|
||||
commonFindNonVerWithLock(LockModeType.NONE);
|
||||
commonFindNonVerWithLock(LockModeType.READ);
|
||||
commonFindNonVerWithLock(LockModeType.WRITE);
|
||||
commonFindNonVerWithLock(LockModeType.OPTIMISTIC);
|
||||
commonFindNonVerWithLock(LockModeType.OPTIMISTIC_FORCE_INCREMENT);
|
||||
commonFindNonVerWithLock(LockModeType.PESSIMISTIC_READ);
|
||||
commonFindNonVerWithLock(LockModeType.PESSIMISTIC_WRITE);
|
||||
commonFindNonVerWithLock(LockModeType.PESSIMISTIC_FORCE_INCREMENT);
|
||||
}
|
||||
|
||||
private void commonFindNonVerWithLock(LockModeType lockMode) {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
|
||||
em.getTransaction().begin();
|
||||
LockEmployeeNonVersion emp = em.find(LockEmployeeNonVersion.class, 1,
|
||||
lockMode);
|
||||
assertNotNull(emp);
|
||||
String lastLastName = emp.getLastName();
|
||||
em.getTransaction().commit();
|
||||
|
||||
em.clear();
|
||||
|
||||
em.getTransaction().begin();
|
||||
emp = em.find(LockEmployeeNonVersion.class, 1);
|
||||
assertNotNull(emp);
|
||||
assertEquals(lastLastName, emp.getLastName());
|
||||
|
||||
emp = em.find(LockEmployeeNonVersion.class, 1, lockMode);
|
||||
emp.setLastName(lockMode.toString());
|
||||
em.getTransaction().commit();
|
||||
|
||||
emp = em.find(LockEmployeeNonVersion.class, 1);
|
||||
assertNotNull(emp);
|
||||
assertEquals(lockMode.toString(), emp.getLastName());
|
||||
|
||||
em.close();
|
||||
}
|
||||
|
||||
/*
|
||||
* Test em.lock(lockMode) on non-versioned entity.
|
||||
*/
|
||||
public void testLockNonVersionWithLock() {
|
||||
commonLockNonVerWithLock(LockModeType.NONE);
|
||||
commonLockNonVerWithLock(LockModeType.READ);
|
||||
commonLockNonVerWithLock(LockModeType.WRITE);
|
||||
commonLockNonVerWithLock(LockModeType.OPTIMISTIC);
|
||||
commonLockNonVerWithLock(LockModeType.OPTIMISTIC_FORCE_INCREMENT);
|
||||
commonLockNonVerWithLock(LockModeType.PESSIMISTIC_READ);
|
||||
commonLockNonVerWithLock(LockModeType.PESSIMISTIC_WRITE);
|
||||
commonLockNonVerWithLock(LockModeType.PESSIMISTIC_FORCE_INCREMENT);
|
||||
}
|
||||
|
||||
private void commonLockNonVerWithLock(LockModeType lockMode) {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
|
||||
em.getTransaction().begin();
|
||||
LockEmployeeNonVersion emp = em.find(LockEmployeeNonVersion.class, 1);
|
||||
assertNotNull(emp);
|
||||
em.lock(emp, lockMode);
|
||||
String lastLastName = emp.getLastName();
|
||||
em.getTransaction().commit();
|
||||
|
||||
em.clear();
|
||||
|
||||
em.getTransaction().begin();
|
||||
emp = em.find(LockEmployeeNonVersion.class, 1);
|
||||
assertNotNull(emp);
|
||||
assertEquals(lastLastName, emp.getLastName());
|
||||
|
||||
emp = em.find(LockEmployeeNonVersion.class, 2);
|
||||
em.lock(emp, lockMode);
|
||||
emp.setLastName(lockMode.toString());
|
||||
em.getTransaction().commit();
|
||||
|
||||
emp = em.find(LockEmployeeNonVersion.class, 2);
|
||||
assertNotNull(emp);
|
||||
assertEquals(lockMode.toString(), emp.getLastName());
|
||||
|
||||
em.close();
|
||||
}
|
||||
|
||||
/*
|
||||
* Test em.refresh(lockMode) on non-versioned entity.
|
||||
*/
|
||||
public void testRefreshNonVersionWithLock() {
|
||||
commonRefreshNonVerWithLock(LockModeType.NONE);
|
||||
commonRefreshNonVerWithLock(LockModeType.READ);
|
||||
commonRefreshNonVerWithLock(LockModeType.WRITE);
|
||||
commonRefreshNonVerWithLock(LockModeType.OPTIMISTIC);
|
||||
commonRefreshNonVerWithLock(LockModeType.OPTIMISTIC_FORCE_INCREMENT);
|
||||
commonRefreshNonVerWithLock(LockModeType.PESSIMISTIC_READ);
|
||||
commonRefreshNonVerWithLock(LockModeType.PESSIMISTIC_WRITE);
|
||||
commonRefreshNonVerWithLock(LockModeType.PESSIMISTIC_FORCE_INCREMENT);
|
||||
}
|
||||
|
||||
private void commonRefreshNonVerWithLock(LockModeType lockMode) {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
|
||||
em.getTransaction().begin();
|
||||
LockEmployeeNonVersion emp = em.find(LockEmployeeNonVersion.class, 1);
|
||||
assertNotNull(emp);
|
||||
String lastLastName = emp.getLastName();
|
||||
em.refresh(emp, lockMode);
|
||||
assertEquals(lastLastName, emp.getLastName());
|
||||
em.getTransaction().commit();
|
||||
|
||||
em.clear();
|
||||
|
||||
em.getTransaction().begin();
|
||||
emp = em.find(LockEmployeeNonVersion.class, 1);
|
||||
assertNotNull(emp);
|
||||
assertEquals(lastLastName, emp.getLastName());
|
||||
|
||||
emp = em.find(LockEmployeeNonVersion.class, 3);
|
||||
em.refresh(emp, lockMode);
|
||||
emp.setLastName(lockMode.toString());
|
||||
em.getTransaction().commit();
|
||||
|
||||
emp = em.find(LockEmployeeNonVersion.class, 3);
|
||||
assertNotNull(emp);
|
||||
assertEquals(lockMode.toString(), emp.getLastName());
|
||||
|
||||
em.close();
|
||||
}
|
||||
|
||||
protected void commonSetUp() {
|
||||
empTableName = getMapping(LockEmployeeNonVersion.class).getTable()
|
||||
.getFullName();
|
||||
|
||||
cleanupDB();
|
||||
|
||||
LockEmployeeNonVersion e1, e2, e3;
|
||||
e1 = newEmployee(1);
|
||||
e2 = newEmployee(2);
|
||||
e3 = newEmployee(3);
|
||||
|
||||
resetSQL();
|
||||
EntityManager em = null;
|
||||
try {
|
||||
em = emf.createEntityManager();
|
||||
em.getTransaction().begin();
|
||||
em.persist(e1);
|
||||
em.persist(e2);
|
||||
em.persist(e3);
|
||||
em.getTransaction().commit();
|
||||
} finally {
|
||||
if (em != null && em.isOpen()) {
|
||||
em.close();
|
||||
}
|
||||
}
|
||||
assertAllSQLInOrder("INSERT INTO " + empTableName + " .*");
|
||||
}
|
||||
|
||||
private void cleanupDB() {
|
||||
EntityManager em = null;
|
||||
try {
|
||||
em = emf.createEntityManager();
|
||||
em.getTransaction().begin();
|
||||
|
||||
em.createQuery("delete from " + empTableName).executeUpdate();
|
||||
|
||||
em.getTransaction().commit();
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (em != null && em.isOpen()) {
|
||||
em.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private LockEmployeeNonVersion newEmployee(int id) {
|
||||
LockEmployeeNonVersion e = new LockEmployeeNonVersion();
|
||||
e.setId(id);
|
||||
return e;
|
||||
}
|
||||
|
||||
protected Log getLog() {
|
||||
return emf.getConfiguration().getLog("Tests");
|
||||
}
|
||||
|
||||
protected Log getDumpStackLog() {
|
||||
return emf.getConfiguration().getLog("DumpStack");
|
||||
}
|
||||
|
||||
protected void logStack(Throwable t) {
|
||||
StringWriter str = new StringWriter();
|
||||
PrintWriter print = new PrintWriter(str);
|
||||
t.printStackTrace(print);
|
||||
getDumpStackLog().trace(str.toString());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue