diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/JPA2LockManager.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/MixedLockManager.java similarity index 75% rename from openjpa-persistence/src/main/java/org/apache/openjpa/persistence/JPA2LockManager.java rename to openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/MixedLockManager.java index 1281ba4be..f2377fc49 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/JPA2LockManager.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/MixedLockManager.java @@ -16,29 +16,29 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.openjpa.persistence; +package org.apache.openjpa.jdbc.kernel; import java.sql.SQLException; -import org.apache.openjpa.jdbc.conf.JDBCConfiguration; -import org.apache.openjpa.jdbc.kernel.PessimisticLockManager; import org.apache.openjpa.jdbc.meta.ClassMapping; import org.apache.openjpa.jdbc.sql.SQLExceptions; import org.apache.openjpa.jdbc.sql.Select; +import org.apache.openjpa.kernel.MixedLockLevels; import org.apache.openjpa.kernel.OpenJPAStateManager; import org.apache.openjpa.lib.util.Localizer; +import org.apache.openjpa.util.OptimisticException; /** - * Test JPA 2.0 LockTypeMode semantics using JPA 2.0 "mixed" - * lock manager. + * Mixed lock manager implements both optimistic and pessimistic locking + * semantics in parallel to the JPA 2.0 specification. * * @author Albert Lee * @since 2.0.0 */ -public class JPA2LockManager extends PessimisticLockManager { +public class MixedLockManager extends PessimisticLockManager { private static final Localizer _loc = Localizer - .forPackage(JPA2LockManager.class); + .forPackage(MixedLockManager.class); /* * (non-Javadoc) @@ -46,7 +46,7 @@ public class JPA2LockManager extends PessimisticLockManager { * #selectForUpdate(org.apache.openjpa.jdbc.sql.Select,int) */ public boolean selectForUpdate(Select sel, int lockLevel) { - return (lockLevel >= JPA2LockLevels.LOCK_PESSIMISTIC_READ) + return (lockLevel >= MixedLockLevels.LOCK_PESSIMISTIC_READ) ? super.selectForUpdate(sel, lockLevel) : false; } @@ -58,15 +58,15 @@ public class JPA2LockManager extends PessimisticLockManager { */ protected void lockInternal(OpenJPAStateManager sm, int level, int timeout, Object sdata, boolean postLockVersionCheck) { - if (level >= JPA2LockLevels.LOCK_PESSIMISTIC_FORCE_INCREMENT) { + if (level >= MixedLockLevels.LOCK_PESSIMISTIC_FORCE_INCREMENT) { setVersionCheckOnReadLock(true); setVersionUpdateOnWriteLock(true); super.lockInternal(sm, level, timeout, sdata, postLockVersionCheck); - } else if (level >= JPA2LockLevels.LOCK_PESSIMISTIC_READ) { + } else if (level >= MixedLockLevels.LOCK_PESSIMISTIC_READ) { setVersionCheckOnReadLock(true); setVersionUpdateOnWriteLock(false); super.lockInternal(sm, level, timeout, sdata, postLockVersionCheck); - } else if (level >= JPA2LockLevels.LOCK_OPTIMISTIC) { + } else if (level >= MixedLockLevels.LOCK_OPTIMISTIC) { setVersionCheckOnReadLock(true); setVersionUpdateOnWriteLock(true); optimisticLockInternal(sm, level, timeout, sdata, @@ -79,19 +79,18 @@ public class JPA2LockManager extends PessimisticLockManager { super.optimisticLockInternal(sm, level, timeout, sdata, postLockVersionCheck); if (postLockVersionCheck) { - if (level >= JPA2LockLevels.LOCK_PESSIMISTIC_READ) { + if (level >= MixedLockLevels.LOCK_PESSIMISTIC_READ) { ClassMapping mapping = (ClassMapping) sm.getMetaData(); try { if (!mapping.getVersion().checkVersion(sm, this.getStore(), true)) { - throw new OptimisticLockException(_loc.get( - "optimistic-violation-lock").getMessage(), null, sm - .getManagedInstance(), true); + throw (new OptimisticException(_loc.get( + "optimistic-violation-lock").getMessage())) + .setFailedObject(sm.getObjectId()); } } catch (SQLException se) { - throw SQLExceptions.getStore(se, - ((JDBCConfiguration) getContext().getConfiguration()) - .getDBDictionaryInstance()); + throw SQLExceptions.getStore(se, sm.getObjectId(), + getStore().getDBDictionary()); } } } diff --git a/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/kernel/localizer.properties b/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/kernel/localizer.properties index 8cdc8b5cd..fecdddba8 100644 --- a/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/kernel/localizer.properties +++ b/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/kernel/localizer.properties @@ -139,4 +139,6 @@ uparam-missing: Parameter {0} in SQL Query "{1}" is not given a value. The \ finder-cached: Cached finder for "{0}" SQL: "{1}" finder-not-cachable: Finder for "{0}" is not cachable. finder-add-pattern: Exclusion pattern "{0}" for finder query has invalidated \ - {1} existing entries "{2}" \ No newline at end of file + {1} existing entries "{2}" +optimistic-violation-lock: An optimistic lock violation was detected when \ + locking object instance. \ No newline at end of file diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/MixedLockLevels.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/MixedLockLevels.java new file mode 100644 index 000000000..3b1a89e8a --- /dev/null +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/MixedLockLevels.java @@ -0,0 +1,56 @@ +/* + * 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.kernel; + +/** + * Defines lock levels used for MixedLockManager. + * + * @author Albert Lee + * @since 2.0.0 + */ +public interface MixedLockLevels extends LockLevels { + + /** + * Generic optimistic read lock level. Value of 10. + * + */ + public static final int LOCK_OPTIMISTIC = LOCK_READ; + + /** + * Generic optimistic write lock level. Value of 20. + */ + public static final int LOCK_OPTIMISTIC_FORCE_INCREMENT = + LockLevels.LOCK_WRITE; + + /** + * Generic pessimistic read lock level. Value of 30. + */ + public static final int LOCK_PESSIMISTIC_READ = 30; + + /** + * Generic pessimistic write lock level. Value of 40. + */ + public static final int LOCK_PESSIMISTIC_WRITE = 40; + + /** + * Generic pessimistic force increment level. Value of 50. + */ + public static final int LOCK_PESSIMISTIC_FORCE_INCREMENT = 50; + +} diff --git a/openjpa-persistence/pom.xml b/openjpa-persistence/pom.xml index 8d1560eb6..a90f40c7d 100644 --- a/openjpa-persistence/pom.xml +++ b/openjpa-persistence/pom.xml @@ -39,11 +39,6 @@ openjpa-kernel ${pom.version} - - org.apache.openjpa - openjpa-jdbc - ${pom.version} - org.apache.geronimo.specs geronimo-jpa_2.0_spec diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java index 92a23aad7..0abf0d069 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java @@ -48,13 +48,12 @@ import org.apache.openjpa.conf.OpenJPAConfiguration; import org.apache.openjpa.ee.ManagedRuntime; import org.apache.openjpa.enhance.PCEnhancer; import org.apache.openjpa.enhance.PCRegistry; -import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration; import org.apache.openjpa.kernel.AbstractBrokerFactory; import org.apache.openjpa.kernel.Broker; import org.apache.openjpa.kernel.DelegatingBroker; import org.apache.openjpa.kernel.FetchConfiguration; import org.apache.openjpa.kernel.FindCallbacks; -import org.apache.openjpa.kernel.LockLevels; +import org.apache.openjpa.kernel.MixedLockLevels; import org.apache.openjpa.kernel.OpCallbacks; import org.apache.openjpa.kernel.OpenJPAStateManager; import org.apache.openjpa.kernel.PreparedQuery; @@ -1075,13 +1074,14 @@ public class EntityManagerImpl public LockModeType getLockMode(Object entity) { assertNotCloseInvoked(); - return JPA2LockLevels.fromLockLevel(_broker.getLockLevel(entity)); + return MixedLockLevelsHelper.fromLockLevel( + _broker.getLockLevel(entity)); } public void lock(Object entity, LockModeType mode) { assertNotCloseInvoked(); assertValidAttchedEntity(entity); - _broker.lock(entity, JPA2LockLevels.toLockLevel(mode), -1, this); + _broker.lock(entity, MixedLockLevelsHelper.toLockLevel(mode), -1, this); } public void lock(Object entity) { @@ -1093,7 +1093,8 @@ public class EntityManagerImpl public void lock(Object entity, LockModeType mode, int timeout) { assertNotCloseInvoked(); assertValidAttchedEntity(entity); - _broker.lock(entity, JPA2LockLevels.toLockLevel(mode), timeout, this); + _broker.lock(entity, MixedLockLevelsHelper.toLockLevel(mode), timeout, + this); } public void lock(Object entity, LockModeType mode, @@ -1104,8 +1105,8 @@ public class EntityManagerImpl boolean fcPushed = pushLockProperties(mode, properties); try { - _broker.lock(entity, JPA2LockLevels.toLockLevel(mode), _broker - .getFetchConfiguration().getLockTimeout(), this); + _broker.lock(entity, MixedLockLevelsHelper.toLockLevel(mode), + _broker.getFetchConfiguration().getLockTimeout(), this); } finally { popLockProperties(fcPushed); } @@ -1118,7 +1119,8 @@ public class EntityManagerImpl public void lockAll(Collection entities, LockModeType mode, int timeout) { assertNotCloseInvoked(); - _broker.lockAll(entities, JPA2LockLevels.toLockLevel(mode), timeout, this); + _broker.lockAll(entities, MixedLockLevelsHelper.toLockLevel(mode), + timeout, this); } public void lockAll(Object... entities) { @@ -1571,7 +1573,7 @@ public class EntityManagerImpl fCfg.setLockTimeout(value); break; case ReadLockLevel: - if (value != LockLevels.LOCK_NONE + if (value != MixedLockLevels.LOCK_NONE && value != fCfg.getReadLockLevel()) { if (!fcPushed) { fCfg = _broker.pushFetchConfiguration(); @@ -1581,7 +1583,7 @@ public class EntityManagerImpl } break; case WriteLockLevel: - if (value != LockLevels.LOCK_NONE + if (value != MixedLockLevels.LOCK_NONE && value != fCfg.getWriteLockLevel()) { if (!fcPushed) { fCfg = _broker.pushFetchConfiguration(); @@ -1613,8 +1615,8 @@ public class EntityManagerImpl FetchConfigProperty.WriteLockLevel }, properties); } // override with the specific lockMode, if needed. - int setReadLevel = JPA2LockLevels.toLockLevel(mode); - if (setReadLevel != JPA2LockLevels.LOCK_NONE) { + int setReadLevel = MixedLockLevelsHelper.toLockLevel(mode); + if (setReadLevel != MixedLockLevels.LOCK_NONE) { // Set overriden read lock level FetchConfiguration fCfg = _broker.getFetchConfiguration(); int curReadLevel = fCfg.getReadLockLevel(); @@ -1627,13 +1629,13 @@ public class EntityManagerImpl } // Set overriden isolation level for pessimistic-read/write switch (setReadLevel) { - case JPA2LockLevels.LOCK_PESSIMISTIC_READ: + case MixedLockLevels.LOCK_PESSIMISTIC_READ: fcPushed = setIsolationForPessimisticLock(fCfg, fcPushed, Connection.TRANSACTION_REPEATABLE_READ); break; - case JPA2LockLevels.LOCK_PESSIMISTIC_WRITE: - case JPA2LockLevels.LOCK_PESSIMISTIC_FORCE_INCREMENT: + case MixedLockLevels.LOCK_PESSIMISTIC_WRITE: + case MixedLockLevels.LOCK_PESSIMISTIC_FORCE_INCREMENT: fcPushed = setIsolationForPessimisticLock(fCfg, fcPushed, Connection.TRANSACTION_SERIALIZABLE); break; @@ -1650,7 +1652,8 @@ public class EntityManagerImpl fCfg = _broker.pushFetchConfiguration(); fcPushed = true; } - ((JDBCFetchConfiguration) fCfg).setIsolation(level); + // TODO: refactoring under OPENJPA-957 +// ((JDBCFetchConfiguration) fCfg).setIsolation(level); return fcPushed; } diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/FetchPlanImpl.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/FetchPlanImpl.java index 3119116da..648d4cf39 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/FetchPlanImpl.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/FetchPlanImpl.java @@ -23,12 +23,12 @@ import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.Map; -import java.util.Set; import javax.persistence.LockModeType; import org.apache.openjpa.kernel.DelegatingFetchConfiguration; import org.apache.openjpa.kernel.FetchConfiguration; +import org.apache.openjpa.kernel.MixedLockLevels; /** * Implements FetchPlan via delegation to FetchConfiguration. @@ -245,20 +245,20 @@ public class FetchPlanImpl } public LockModeType getReadLockMode() { - return JPA2LockLevels.fromLockLevel(_fetch.getReadLockLevel()); + return MixedLockLevelsHelper.fromLockLevel(_fetch.getReadLockLevel()); } public FetchPlan setReadLockMode(LockModeType mode) { - _fetch.setReadLockLevel(JPA2LockLevels.toLockLevel(mode)); + _fetch.setReadLockLevel(MixedLockLevelsHelper.toLockLevel(mode)); return this; } public LockModeType getWriteLockMode() { - return JPA2LockLevels.fromLockLevel(_fetch.getWriteLockLevel()); + return MixedLockLevelsHelper.fromLockLevel(_fetch.getWriteLockLevel()); } public FetchPlan setWriteLockMode(LockModeType mode) { - _fetch.setWriteLockLevel(JPA2LockLevels.toLockLevel(mode)); + _fetch.setWriteLockLevel(MixedLockLevelsHelper.toLockLevel(mode)); return this; } diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/JPA2LockLevels.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/JPA2LockLevels.java deleted file mode 100644 index 705f42a11..000000000 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/JPA2LockLevels.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * 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.LockModeType; - -import org.apache.openjpa.kernel.LockLevels; - -/** - * Defines lock levels as per JPA 2.0 specification. - * - * Translates JPA-defined lock levels and OpenJPA internal lock levels. - * - * @author Albert Lee - * @since 2.0.0 - */ -public class JPA2LockLevels { - /** - * Generic optimistic no lock level. Defined since JPA 1.0. - * - */ - public static final int LOCK_NONE = LockLevels.LOCK_NONE; - - /** - * Generic optimistic read lock level. Defined since JPA 1.0. - * Equivalent to LOCK_OPTIMISTIC which is preferred. - */ - public static final int LOCK_READ = LockLevels.LOCK_READ; - - /** - * Generic optimistic read lock level. Defined since JPA 2.0. - * Value of 10. - * - */ - public static final int LOCK_OPTIMISTIC = LOCK_READ; - - /** - * Generic optimistic write lock level. Value of 20. - */ - public static final int LOCK_OPTIMISTIC_FORCE_INCREMENT = - LockLevels.LOCK_WRITE; - - /** - * Generic pessimistic read lock level. Value of 30. - */ - public static final int LOCK_PESSIMISTIC_READ = 30; - - /** - * Generic pessimistic write lock level. Value of 40. - */ - public static final int LOCK_PESSIMISTIC_WRITE = 40; - - /** - * Generic pessimistic force increment level. Value of 50. - */ - public static final int LOCK_PESSIMISTIC_FORCE_INCREMENT = 50; - - /** - * Translates the javax.persistence enum value to our internal lock level. - */ - public static int toLockLevel(LockModeType mode) { - if (mode == null || mode == LockModeType.NONE) - return LockLevels.LOCK_NONE; - if (mode == LockModeType.READ || mode == LockModeType.OPTIMISTIC) - return LockLevels.LOCK_READ; - if (mode == LockModeType.WRITE - || mode == LockModeType.OPTIMISTIC_FORCE_INCREMENT) - return LockLevels.LOCK_WRITE; - // TODO: if (mode == LockModeType.PESSIMISTIC_READ) - // TODO: return LockLevels.LOCK_PESSIMISTIC_READ; - if (mode == LockModeType.PESSIMISTIC) - return LOCK_PESSIMISTIC_WRITE; - if (mode == LockModeType.PESSIMISTIC_FORCE_INCREMENT) - return LOCK_PESSIMISTIC_FORCE_INCREMENT; - throw new ArgumentException(mode.toString(), null, null, true); - } - - /** - * Translate our internal lock level to a javax.persistence enum value. - */ - public static LockModeType fromLockLevel(int level) { - if (level < LOCK_OPTIMISTIC) - return null; - if (level < LOCK_OPTIMISTIC_FORCE_INCREMENT) - return LockModeType.READ; - if (level < LOCK_PESSIMISTIC_READ) - return LockModeType.WRITE; - if (level < LOCK_PESSIMISTIC_WRITE) - return LockModeType.PESSIMISTIC; - // TODO: return LockModeType.PESSIMISTIC_READ; - if (level < LOCK_PESSIMISTIC_FORCE_INCREMENT) - return LockModeType.PESSIMISTIC; - // TODO: return LockModeType.PESSIMISTIC_WRITE; - return LockModeType.PESSIMISTIC_FORCE_INCREMENT; - } -} diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/MixedLockLevelsHelper.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/MixedLockLevelsHelper.java new file mode 100644 index 000000000..39da533a7 --- /dev/null +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/MixedLockLevelsHelper.java @@ -0,0 +1,69 @@ +/* + * 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.LockModeType; + +import org.apache.openjpa.kernel.MixedLockLevels; + +/** + * Helper methods translate between JPA-defined lock mode and OpenJPA + * internal lock levels. + * + * @author Albert Lee + * @since 2.0.0 + */ +public class MixedLockLevelsHelper { + /** + * Translates javax.persistence LockModeType to internal lock level. + */ + public static int toLockLevel(LockModeType mode) { + if (mode == null || mode == LockModeType.NONE) + return MixedLockLevels.LOCK_NONE; + if (mode == LockModeType.READ || mode == LockModeType.OPTIMISTIC) + return MixedLockLevels.LOCK_READ; + if (mode == LockModeType.WRITE + || mode == LockModeType.OPTIMISTIC_FORCE_INCREMENT) + return MixedLockLevels.LOCK_WRITE; + // TODO: if (mode == LockModeType.PESSIMISTIC_READ) + // TODO: return LockLevels.LOCK_PESSIMISTIC_READ; + if (mode == LockModeType.PESSIMISTIC) + return MixedLockLevels.LOCK_PESSIMISTIC_WRITE; + return MixedLockLevels.LOCK_PESSIMISTIC_FORCE_INCREMENT; + } + + /** + * Translates internal lock level to javax.persistence LockModeType. + */ + public static LockModeType fromLockLevel(int level) { + if (level < MixedLockLevels.LOCK_OPTIMISTIC) + return null; + if (level < MixedLockLevels.LOCK_OPTIMISTIC_FORCE_INCREMENT) + return LockModeType.READ; + if (level < MixedLockLevels.LOCK_PESSIMISTIC_READ) + return LockModeType.WRITE; + if (level < MixedLockLevels.LOCK_PESSIMISTIC_WRITE) + return LockModeType.PESSIMISTIC; + // TODO: return LockModeType.PESSIMISTIC_READ; + if (level < MixedLockLevels.LOCK_PESSIMISTIC_FORCE_INCREMENT) + return LockModeType.PESSIMISTIC; + // TODO: return LockModeType.PESSIMISTIC_WRITE; + return LockModeType.PESSIMISTIC_FORCE_INCREMENT; + } +} diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceExceptions.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceExceptions.java index 579aad2f4..0716ef200 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceExceptions.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceExceptions.java @@ -14,13 +14,14 @@ * "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. + * under the License. */ package org.apache.openjpa.persistence; import java.lang.reflect.InvocationTargetException; import org.apache.openjpa.kernel.Broker; +import org.apache.openjpa.kernel.MixedLockLevels; import org.apache.openjpa.util.Exceptions; import org.apache.openjpa.util.LockException; import org.apache.openjpa.util.NoTransactionException; @@ -147,25 +148,25 @@ public class PersistenceExceptions */ private static Throwable translateStoreException(OpenJPAException ke) { Exception e; - Throwable cause = (ke.getNestedThrowables() != null + Throwable cause = (ke.getNestedThrowables() != null && ke.getNestedThrowables().length == 1) ? ke.getNestedThrowables()[0] : null; - if (ke.getSubtype() == StoreException.OBJECT_NOT_FOUND + if (ke.getSubtype() == StoreException.OBJECT_NOT_FOUND || cause instanceof ObjectNotFoundException) { e = new org.apache.openjpa.persistence.EntityNotFoundException (ke.getMessage(), getNestedThrowables(ke), getFailedObject(ke), ke.isFatal()); - } else if (ke.getSubtype() == StoreException.OPTIMISTIC + } else if (ke.getSubtype() == StoreException.OPTIMISTIC || cause instanceof OptimisticException) { e = new org.apache.openjpa.persistence.OptimisticLockException (ke.getMessage(), getNestedThrowables(ke), getFailedObject(ke), ke.isFatal()); - } else if (ke.getSubtype() == StoreException.LOCK + } else if (ke.getSubtype() == StoreException.LOCK || cause instanceof LockException) { LockException lockEx = (LockException) (ke instanceof LockException ? ke : cause); - if (lockEx != null && lockEx.getLockLevel() >= - JPA2LockLevels.LOCK_PESSIMISTIC_READ) { + if (lockEx != null && lockEx.getLockLevel() >= + MixedLockLevels.LOCK_PESSIMISTIC_READ) { if (!lockEx.isFatal()) { e = new org.apache.openjpa.persistence .LockTimeoutException( @@ -211,10 +212,10 @@ public class PersistenceExceptions /** * Translate the given user exception. - * If a {link {@link OpenJPAException#getSubtype() sub type} is set on the + * If a {link {@link OpenJPAException#getSubtype() sub type} is set on the * given exception then a corresponding facade-level exception i.e. the * exceptions that inherit JPA-defined exceptions is generated. - * If given exception is not further classified to a sub type, then + * If given exception is not further classified to a sub type, then * an [@link {@link #translateInternalException(OpenJPAException)} attempt} * is made to translate the given OpenJPAException by its internal cause. */ @@ -222,7 +223,7 @@ public class PersistenceExceptions Exception e; switch (ke.getSubtype()) { case UserException.NO_TRANSACTION: - e = new + e = new org.apache.openjpa.persistence.TransactionRequiredException (ke.getMessage(), getNestedThrowables(ke), getFailedObject(ke), ke.isFatal()); @@ -248,16 +249,17 @@ public class PersistenceExceptions e.setStackTrace(ke.getStackTrace()); return e; } - + /** - * Translate to a facade-level exception if the given exception - * a) has a cause i.e. one and only nested Throwable - * and b) that cause is one of the known internal exception which has a - * direct facade-level counterpart - * (for example, ObjectNotFoundException can be translated to - * EntityNotFoundException). - * If the above conditions are not met then return generic ArgumentException. - * + * Translate to a facade-level exception if the given exception + * a) has a cause i.e. one and only nested Throwable + * and b) that cause is one of the known internal exception which has a + * direct facade-level counterpart + * (for example, ObjectNotFoundException can be translated to + * EntityNotFoundException). + * If the above conditions are not met then return generic + * ArgumentException. + * * In either case, preserve all the details. */ private static Exception translateCause(OpenJPAException ke) { diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java index 8d69e8996..9fd0c64da 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java @@ -40,6 +40,7 @@ import org.apache.openjpa.conf.OpenJPAConfiguration; import org.apache.openjpa.conf.OpenJPAConfigurationImpl; import org.apache.openjpa.conf.OpenJPAProductDerivation; import org.apache.openjpa.conf.Specification; +import org.apache.openjpa.kernel.MixedLockLevels; import org.apache.openjpa.lib.conf.AbstractProductDerivation; import org.apache.openjpa.lib.conf.Configuration; import org.apache.openjpa.lib.conf.ConfigurationProvider; @@ -110,29 +111,29 @@ public class PersistenceProductDerivation conf.addValue(new EntityManagerFactoryValue()); conf.readLockLevel.setAlias("optimistic", String - .valueOf(JPA2LockLevels.LOCK_OPTIMISTIC)); + .valueOf(MixedLockLevels.LOCK_OPTIMISTIC)); conf.readLockLevel.setAlias("optimistic-force-increment", String - .valueOf(JPA2LockLevels.LOCK_OPTIMISTIC_FORCE_INCREMENT)); + .valueOf(MixedLockLevels.LOCK_OPTIMISTIC_FORCE_INCREMENT)); conf.readLockLevel.setAlias("pessimistic-read", String - .valueOf(JPA2LockLevels.LOCK_PESSIMISTIC_READ)); + .valueOf(MixedLockLevels.LOCK_PESSIMISTIC_READ)); conf.readLockLevel.setAlias("pessimistic-write", String - .valueOf(JPA2LockLevels.LOCK_PESSIMISTIC_WRITE)); + .valueOf(MixedLockLevels.LOCK_PESSIMISTIC_WRITE)); conf.readLockLevel.setAlias("pessimistic-force-increment", String - .valueOf(JPA2LockLevels.LOCK_PESSIMISTIC_FORCE_INCREMENT)); + .valueOf(MixedLockLevels.LOCK_PESSIMISTIC_FORCE_INCREMENT)); conf.writeLockLevel.setAlias("optimistic", String - .valueOf(JPA2LockLevels.LOCK_OPTIMISTIC)); + .valueOf(MixedLockLevels.LOCK_OPTIMISTIC)); conf.writeLockLevel.setAlias("optimistic-force-increment", String - .valueOf(JPA2LockLevels.LOCK_OPTIMISTIC_FORCE_INCREMENT)); + .valueOf(MixedLockLevels.LOCK_OPTIMISTIC_FORCE_INCREMENT)); conf.writeLockLevel.setAlias("pessimistic-read", String - .valueOf(JPA2LockLevels.LOCK_PESSIMISTIC_READ)); + .valueOf(MixedLockLevels.LOCK_PESSIMISTIC_READ)); conf.writeLockLevel.setAlias("pessimistic-write", String - .valueOf(JPA2LockLevels.LOCK_PESSIMISTIC_WRITE)); + .valueOf(MixedLockLevels.LOCK_PESSIMISTIC_WRITE)); conf.writeLockLevel.setAlias("pessimistic-force-increment", String - .valueOf(JPA2LockLevels.LOCK_PESSIMISTIC_FORCE_INCREMENT)); + .valueOf(MixedLockLevels.LOCK_PESSIMISTIC_FORCE_INCREMENT)); conf.lockManagerPlugin.setAlias("mixed", - JPA2LockManager.class.getName()); + "org.apache.openjpa.jdbc.kernel.MixedLockManager"); return true; } @@ -633,7 +634,8 @@ public class PersistenceProductDerivation return; switch (name.charAt(0)) { - // cases 'name' and 'transaction-type' are handled in startPersistenceUnit() + // cases 'name' and 'transaction-type' are handled in + // startPersistenceUnit() // case 'property' for 'properties' is handled in startElement() case 'c': // class _info.addManagedClassName(currentText()); diff --git a/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties b/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties index ae4a2f340..e1d63b6e1 100644 --- a/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties +++ b/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties @@ -167,7 +167,5 @@ no-result: Query "{0}" selected no result, but expected unique result. non-unique-result: Query "{0}" selected {1} results, but expected unique result. unwrap-em-invalid: EntityManager can not be unwrapped to an instance of "{0}". unwrap-query-invalid: Query can not be unwrapped to an instance of "{0}". -optimistic-violation-lock: An optimistic lock violation was detected when \ - locking object instance. invalid_entity_argument: Object being locked must be an valid and not detached \ entity. diff --git a/openjpa-project/src/doc/manual/ref_guide_runtime.xml b/openjpa-project/src/doc/manual/ref_guide_runtime.xml index 4e2f02e4b..30296f0dd 100644 --- a/openjpa-project/src/doc/manual/ref_guide_runtime.xml +++ b/openjpa-project/src/doc/manual/ref_guide_runtime.xml @@ -526,7 +526,10 @@ through the openjpa.ReadLockLevel and openjpa.WriteLockLevel configuration properties. Each property accepts a value of -none, read, write, or a number +none, read, write, +optimistic, optimistic-force-increment, +pessimistic-read, pessimistic-write, +pessimistic-force-increment, or a number corresponding to a lock level defined by the lock manager in use. These properties apply only to non-optimistic transactions; during optimistic @@ -729,12 +732,12 @@ own lock manager, or use one of the bundled options: mixed: This is an alias for the - -org.apache.openjpa.persistence.JPA2LockManager + +org.apache.openjpa.jdbc.kernel.MixedLockManager , which implements the JPA 2.0 specification entity locking behaviors. It combines both the optimistic and pessimistic semantics controlled by -lock modes argument in methods define in the entity manager -and query interfaces or OpenJPA lock level properties. +lock mode argument in methods define in the EntityManager +and Query interfaces or OpenJPA lock level properties. The mixed LockManager inherits all the properties available @@ -743,7 +746,7 @@ For example: VersionCheckOnReadLock and VersionUpdateOnWriteLock properties. -This is the default openjpa.LockManager setting in JPA. +This is the default openjpa.LockManager setting in OpenJPA.