This is an automated email from the ASF dual-hosted git repository. pcristof pushed a commit to branch OPENJPA-2940 in repository https://gitbox.apache.org/repos/asf/openjpa.git
The following commit(s) were added to refs/heads/OPENJPA-2940 by this push: new ffb548b99 [OPENJPA-2940][WIP] Implementing em.find with FindOption ffb548b99 is described below commit ffb548b994c6c89346cbf1b41125d730954098d8 Author: Paulo Cristovão de Araújo Silva Filho <pcris...@gmail.com> AuthorDate: Fri Aug 15 09:33:35 2025 -0300 [OPENJPA-2940][WIP] Implementing em.find with FindOption --- .../cache/jpa/AbstractCacheModeTestCase.java | 6 ++-- .../persistence/query/TestTimeoutException.java | 33 ++++++++++++++++++++++ .../openjpa/persistence/EntityManagerImpl.java | 29 +++++++++++++++---- 3 files changed, 58 insertions(+), 10 deletions(-) diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/AbstractCacheModeTestCase.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/AbstractCacheModeTestCase.java index 7b57a1e50..d113e4852 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/AbstractCacheModeTestCase.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/AbstractCacheModeTestCase.java @@ -210,10 +210,9 @@ public abstract class AbstractCacheModeTestCase extends AbstractCacheTestCase { @Override public void run() { EntityManager em = getEntityManagerFactory().createEntityManager(); - em.setProperty(RETRIEVE_MODE_PROP, CacheRetrieveMode.USE); for (Class<?> cls : getExpectedInCache()) { assertCached(getEntityManagerFactory().getCache(), cls, 1, true); - assertNotNull(em.find(cls, 1)); + assertNotNull(em.find(cls, 1, CacheRetrieveMode.USE)); } em.close(); } @@ -222,10 +221,9 @@ public abstract class AbstractCacheModeTestCase extends AbstractCacheTestCase { @Override public void run() { EntityManager em = getEntityManagerFactory().createEntityManager(); - em.setProperty(RETRIEVE_MODE_PROP, CacheRetrieveMode.USE); for (Class<?> cls : getExpectedNotInCache()) { assertCached(getEntityManagerFactory().getCache(), cls, 1, false); - assertNotNull(em.find(cls, 1)); + assertNotNull(em.find(cls, 1, CacheRetrieveMode.USE)); } em.close(); } diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestTimeoutException.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestTimeoutException.java index 54b77204d..a85fcf1d1 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestTimeoutException.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestTimeoutException.java @@ -21,8 +21,10 @@ import jakarta.persistence.EntityManager; import jakarta.persistence.LockModeType; import jakarta.persistence.LockTimeoutException; import jakarta.persistence.PessimisticLockException; +import jakarta.persistence.PessimisticLockScope; import jakarta.persistence.Query; import jakarta.persistence.QueryTimeoutException; +import jakarta.persistence.Timeout; import org.apache.openjpa.jdbc.conf.JDBCConfiguration; import org.apache.openjpa.jdbc.sql.DBDictionary; @@ -97,6 +99,37 @@ public class TestTimeoutException extends SingleEMFTestCase { } } + public void testLockTimeOutExceptionWhileQueryingWithLocksOnAlreadyLockedEntitiesOption() { + if (getLog().isTraceEnabled()) + getLog().trace("***** Entered TestTimeoutException." + + "testLockTimeOutExceptionWhileQueryingWithLocksOnAlreadyLockedEntitiesOption()"); + EntityManager em1 = emf.createEntityManager(); + EntityManager em2 = emf.createEntityManager(); + assertNotSame(em1, em2); + Object oid = createEntity(em1); + + em1.getTransaction().begin(); + Object entity = em1.find(entityClass, oid); + assertNotNull(entity); + em1.lock(entity, LockModeType.PESSIMISTIC_WRITE); + + em2.getTransaction().begin(); + Timeout timeout = Timeout.milliseconds(1000); + try { + em2.find(entityClass, emf.getPersistenceUnitUtil().getIdentifier(entity), LockModeType.PESSIMISTIC_WRITE, timeout); + fail("Expected " + LockTimeoutException.class.getName()); + } catch (Throwable t) { + assertError(t, LockTimeoutException.class); + assertTrue(em2.getTransaction().isActive()); + } + finally { + em1.getTransaction().rollback(); + em1.close(); + em2.getTransaction().rollback(); + em2.close(); + } + } + public void testLockTimeOutExceptionWhileLockingAlreadyLockedEntities() { if (getLog().isTraceEnabled()) getLog().trace("***** Entered TestTimeoutException." + 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 f432ab1a6..20da2bcbd 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 @@ -55,6 +55,7 @@ import jakarta.persistence.PessimisticLockScope; import jakarta.persistence.Query; import jakarta.persistence.RefreshOption; import jakarta.persistence.StoredProcedureQuery; +import jakarta.persistence.Timeout; import jakarta.persistence.Tuple; import jakarta.persistence.TypedQuery; import jakarta.persistence.TypedQueryReference; @@ -600,6 +601,27 @@ public class EntityManagerImpl Map<String, Object> properties){ return find(cls, oid, null, properties); } + + @Override + public <T> T find(Class<T> cls, Object oid, FindOption... options) { + Map<String, Object> props = new HashMap<>(); + LockModeType mode = null; + for (FindOption opt: options) { + if (opt instanceof LockModeType lmt) { + mode = lmt; + } else if (opt instanceof CacheRetrieveMode crm) { + props.put(JPAProperties.CACHE_RETRIEVE_MODE, crm); + } else if (opt instanceof CacheStoreMode csm) { + props.put(JPAProperties.CACHE_STORE_MODE, csm); + } else if (opt instanceof PessimisticLockScope pls) { + props.put(JPAProperties.LOCK_SCOPE, pls); + } else if (opt instanceof Timeout timeout) { + props.put(JPAProperties.LOCK_TIMEOUT, timeout.milliseconds()); + } + // open to custom options + } + return find(cls, oid, mode, props); + } @Override @SuppressWarnings("unchecked") @@ -2067,7 +2089,7 @@ public class EntityManagerImpl for (Map.Entry<String, Object> entry : properties.entrySet()) { String key = entry.getKey(); Object value = entry.getValue(); - if (key.equals("jakarta.persistence.lock.scope")) { + if (key.equals(JPAProperties.LOCK_SCOPE)) { fetch.setLockScope((PessimisticLockScope)value); } else fetch.setHint(key, value); @@ -2253,11 +2275,6 @@ public class EntityManagerImpl return meta; } - @Override - public <T> T find(Class<T> entityClass, Object primaryKey, FindOption... options) { - throw new UnsupportedOperationException("Not yet implemented (JPA 3.2)"); - } - @Override public <T> T find(EntityGraph<T> entityGraph, Object primaryKey, FindOption... options) { throw new UnsupportedOperationException("Not yet implemented (JPA 3.2)");