Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

introduce FindOption interface and new overloads of EM.find() #454

Merged
merged 6 commits into from
Aug 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion api/src/main/java/jakarta/persistence/CacheRetrieveMode.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@
* specify the behavior when data is retrieved by the
* <code>find</code> methods and by queries.
*
* @see EntityManager#setCacheRetrieveMode(CacheRetrieveMode)
* @see Query#setCacheRetrieveMode(CacheRetrieveMode)
*
* @since 2.0
*/
public enum CacheRetrieveMode {
public enum CacheRetrieveMode implements FindOption {

/**
* Read entity data from the cache: this is
Expand Down
5 changes: 4 additions & 1 deletion api/src/main/java/jakarta/persistence/CacheStoreMode.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@
* the behavior when data is read from the database and when data is
* committed into the database.
*
* @see EntityManager#setCacheStoreMode(CacheStoreMode)
* @see Query#setCacheStoreMode(CacheStoreMode)
*
* @since 2.0
*/
public enum CacheStoreMode {
public enum CacheStoreMode implements FindOption, RefreshOption {

/**
* Insert entity data into cache when read from database
Expand Down
2 changes: 1 addition & 1 deletion api/src/main/java/jakarta/persistence/EntityGraph.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public interface EntityGraph<T> extends Graph<T> {
* Return the name of a named EntityGraph (an entity graph
* defined by means of the <code>NamedEntityGraph</code>
* annotation, XML descriptor element, or added by means of the
* <code>addNamedEntityGraph</code> method. Returns null if the
* <code>addNamedEntityGraph</code> method). Returns null if the
* EntityGraph is not a named EntityGraph.
*/
public String getName();
Expand Down
240 changes: 237 additions & 3 deletions api/src/main/java/jakarta/persistence/EntityManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,119 @@ public <T> T find(Class<T> entityClass, Object primaryKey,
LockModeType lockMode,
Map<String, Object> properties);

/**
* Find an instance of the given entity class by primary key,
* using the specified {@linkplain FindOption options}.
* Search for an entity with the specified class and primary key.
* If the given options include a {@link LockModeType}, lock it
* with respect to the specified lock type.
* If the entity instance is contained in the persistence context,
* it is returned from there.
* <p>If the entity is found within the persistence context and
* the lock mode type is pessimistic and the entity has a version
* attribute, the persistence provider must perform optimistic
* version checks when obtaining the database lock. If these checks
* fail, the <code>OptimisticLockException</code> will be thrown.
* <p>If the lock mode type is pessimistic and the entity instance
* is found but cannot be locked:
* <ul>
* <li> the <code>PessimisticLockException</code> will be thrown
* if the database locking failure causes transaction-level
* rollback
* <li> the <code>LockTimeoutException</code> will be thrown if
* the database locking failure causes only statement-level
* rollback
* </ul>
* <p>If a vendor-specific {@linkplain FindOption option} is not
* recognized, it is silently ignored.
* <p>Portable applications should not rely on the standard
* {@linkplain Timeout timeout option}. Depending on the database
* in use and the locking mechanisms used by the provider, this
* option may or may not be observed.
* @param entityClass entity class
* @param primaryKey primary key
* @param options standard and vendor-specific options
* @return the found entity instance or null if the entity does
* not exist
* @throws IllegalArgumentException if there are contradictory
* options, if the first argument does not denote an entity
* type belonging to the persistence unit, or if the second
* argument is not a valid non-null instance of the entity
* primary key type
* @throws TransactionRequiredException if there is no transaction
* and a lock mode other than <code>NONE</code> is
* specified or if invoked on an entity manager which has
* not been joined to the current transaction and a lock
* mode other than <code>NONE</code> is specified
* @throws OptimisticLockException if the optimistic version check
* fails
* @throws PessimisticLockException if pessimistic locking fails
* and the transaction is rolled back
* @throws LockTimeoutException if pessimistic locking fails and
* only the statement is rolled back
* @throws PersistenceException if an unsupported lock call is made
* @since 3.2
*/
public <T> T find(Class<T> entityClass, Object primaryKey,
FindOption... options);

/**
* Find an instance of the root entity of the given {@link EntityGraph}
* by primary key, using the specified {@linkplain FindOption options},
* and interpreting the {@code EntityGraph} as a load graph.
* Search for an entity with the specified type and primary key.
* If the given options include a {@link LockModeType}, lock it
* with respect to the specified lock type.
* If the entity instance is contained in the persistence context,
* it is returned from there.
* <p> If the entity is found within the persistence context and
* the lock mode type is pessimistic and the entity has a version
* attribute, the persistence provider must perform optimistic
* version checks when obtaining the database lock. If these checks
* fail, the <code>OptimisticLockException</code> will be thrown.
* <p>If the lock mode type is pessimistic and the entity instance
* is found but cannot be locked:
* <ul>
* <li> the <code>PessimisticLockException</code> will be thrown
* if the database locking failure causes transaction-level
* rollback
* <li> the <code>LockTimeoutException</code> will be thrown if
* the database locking failure causes only statement-level
* rollback
* </ul>
* <p>If a vendor-specific {@linkplain FindOption option} is not
* recognized, it is silently ignored.
* <p>Portable applications should not rely on the standard
* {@linkplain Timeout timeout option}. Depending on the database
* in use and the locking mechanisms used by the provider, this
* option may or may not be observed.
* @param entityGraph entity graph interpreted as a load graph
* @param primaryKey primary key
* @param options standard and vendor-specific options
* @return the found entity instance or null if the entity does
* not exist
* @throws IllegalArgumentException if there are contradictory
* options, if the first argument does not denote an entity
* type belonging to the persistence unit, or if the second
* argument is not a valid non-null instance of the entity
* primary key type
* @throws TransactionRequiredException if there is no transaction
* and a lock mode other than <code>NONE</code> is
* specified or if invoked on an entity manager which has
* not been joined to the current transaction and a lock
* mode other than <code>NONE</code> is specified
* @throws OptimisticLockException if the optimistic version check
* fails
* @throws PessimisticLockException if pessimistic locking fails
* and the transaction is rolled back
* @throws LockTimeoutException if pessimistic locking fails and
* only the statement is rolled back
* @throws PersistenceException if an unsupported lock call is made
* @since 3.2
*/
public <T> T find(EntityGraph<T> entityGraph, Object primaryKey,
FindOption... options);

/**
* Get an instance, whose state may be lazily fetched.
* If the requested instance does not exist in the database,
Expand Down Expand Up @@ -367,6 +480,54 @@ public <T> T getReference(Class<T> entityClass,
public void lock(Object entity, LockModeType lockMode,
Map<String, Object> properties);

/**
* Lock an entity instance that is contained in the persistence
* context with the specified lock mode type, using specified
* {@linkplain LockOption options}.
* <p>If a pessimistic lock mode type is specified and the entity
* contains a version attribute, the persistence provider must
* also perform optimistic version checks when obtaining the
* database lock. If these checks fail, the
* <code>OptimisticLockException</code> will be thrown.
* <p>If the lock mode type is pessimistic and the entity instance
* is found but cannot be locked:
* <ul>
* <li> the <code>PessimisticLockException</code> will be thrown
* if the database locking failure causes transaction-level
* rollback
* <li> the <code>LockTimeoutException</code> will be thrown if
* the database locking failure causes only statement-level
* rollback
* </ul>
* <p>If a vendor-specific {@link LockOption} is not recognized,
* it is silently ignored.
* <p>Portable applications should not rely on the standard
* {@linkplain Timeout timeout option}. Depending on the database
* in use and the locking mechanisms used by the provider, the
* option may or may not be observed.
* @param entity entity instance
* @param lockMode lock mode
* @param options standard and vendor-specific options
* @throws IllegalArgumentException if the instance is not an
* entity or is a detached entity
* @throws TransactionRequiredException if there is no
* transaction or if invoked on an entity manager which
* has not been joined to the current transaction
* @throws EntityNotFoundException if the entity does not exist
* in the database when pessimistic locking is
* performed
* @throws OptimisticLockException if the optimistic version
* check fails
* @throws PessimisticLockException if pessimistic locking fails
* and the transaction is rolled back
* @throws LockTimeoutException if pessimistic locking fails and
* only the statement is rolled back
* @throws PersistenceException if an unsupported lock call is made
* @since 3.2
*/
public void lock(Object entity, LockModeType lockMode,
LockOption... options);

/**
* Refresh the state of the instance from the database,
* overwriting changes made to the entity, if any.
Expand Down Expand Up @@ -400,7 +561,7 @@ public void lock(Object entity, LockModeType lockMode,
* @since 2.0
*/
public void refresh(Object entity,
Map<String, Object> properties);
Map<String, Object> properties);

/**
* Refresh the state of the instance from the database,
Expand Down Expand Up @@ -484,7 +645,52 @@ public void refresh(Object entity,
*/
public void refresh(Object entity, LockModeType lockMode,
Map<String, Object> properties);


/**
* Refresh the state of the given entity instance from the
* database, using the specified {@linkplain RefreshOption options},
* overwriting changes made to the entity, if any. If the supplied
* options include a {@link LockModeType}, lock the given entity with
* respect to the specified lock type.
* <p>If the lock mode type is pessimistic and the entity instance is
* found but cannot be locked:
* <ul>
* <li> the <code>PessimisticLockException</code> will be thrown if
* the database locking failure causes transaction-level rollback
* <li> the <code>LockTimeoutException</code> will be thrown if the
* database locking failure causes only statement-level rollback
* </ul>
* <p>If a vendor-specific {@link RefreshOption} is not recognized,
* it is silently ignored.
* <p>Portable applications should not rely on the standard
* {@linkplain Timeout timeout option}. Depending on the database in
* use and the locking mechanisms used by the provider, the hint may
* or may not be observed.
* @param entity entity instance
* @param options standard and vendor-specific options
* @throws IllegalArgumentException if the instance is not an entity
* or the entity is not managed
* @throws TransactionRequiredException if invoked on a
* container-managed entity manager of type
* <code>PersistenceContextType.TRANSACTION</code> when there
* is no transaction; if invoked on an extended entity manager
* when there is no transaction and a lock mode other than
* <code>NONE</code> has been specified; or if invoked on an
* extended entity manager that has not been joined to the
* current transaction and a lock mode other than
* <code>NONE</code> has been specified
* @throws EntityNotFoundException if the entity no longer exists in
* the database
* @throws PessimisticLockException if pessimistic locking fails and
* the transaction is rolled back
* @throws LockTimeoutException if pessimistic locking fails and only
* the statement is rolled back
* @throws PersistenceException if an unsupported lock call is made
* @since 3.2
*/
public void refresh(Object entity,
RefreshOption... options);

/**
* Clear the persistence context, causing all managed
* entities to become detached. Changes made to entities that
Expand Down Expand Up @@ -529,7 +735,35 @@ public void refresh(Object entity, LockModeType lockMode,
*/
public LockModeType getLockMode(Object entity);

/**
/**
* Set the cache retrieval mode that is in effect during
* query execution. This cache retrieval mode overrides the
* cache retrieve mode in use by the entity manager.
* @param cacheRetrieveMode cache retrieval mode
* @since 3.2
*/
public void setCacheRetrieveMode(CacheRetrieveMode cacheRetrieveMode);

/**
* Set the default cache storage mode for this persistence context.
* @param cacheStoreMode cache storage mode
* @since 3.2
*/
public void setCacheStoreMode(CacheStoreMode cacheStoreMode);

/**
* The cache retrieval mode for this persistence context.
* @since 3.2
*/
public CacheRetrieveMode getCacheRetrieveMode();

/**
* The cache storage mode for this persistence context.
* @since 3.2
*/
public CacheStoreMode getCacheStoreMode();

/**
* Set an entity manager property or hint.
* If a vendor-specific property or hint is not recognized, it is
* silently ignored.
Expand Down
40 changes: 40 additions & 0 deletions api/src/main/java/jakarta/persistence/FindOption.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2008, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/

// Contributors:
// Gavin King - 3.2


package jakarta.persistence;

/**
* An option influencing the behavior of {@link EntityManager#find}.
* Built-in options control {@linkplain LockModeType locking},
* {@linkplain CacheRetrieveMode cache interaction}, and
* {@linkplain Timeout timeouts}.
*
* <p>This interface may be implemented by custom provider-specific
* options which extend the options defined by the specification.
*
* @see LockModeType
* @see PessimisticLockScope
* @see CacheRetrieveMode
* @see CacheStoreMode
* @see Timeout
*
* @see EntityManager#find(Class, Object, FindOption...)
* @see EntityManager#find(EntityGraph, Object, FindOption...)
*
* @since 3.2
*/
public interface FindOption {
}
32 changes: 32 additions & 0 deletions api/src/main/java/jakarta/persistence/Graph.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,38 @@ public interface Graph<T> {
*/
public void addAttributeNode(Attribute<? super T, ?> attribute);

/**
* Remove an attribute node from the entity graph.
* When this graph is interpreted as a load graph, this operation
* suppresses inclusion of an attribute mapped for eager fetching.
* The effect of this call may be overridden by subsequent
* invocations of {@link #addAttributeNode} or {@link #addSubgraph}.
* @param attributeName name of the attribute
* @since 3.2
*/
public void removeAttributeNode(String attributeName);

/**
* Remove an attribute node from the entity graph.
* When this graph is interpreted as a load graph, this operation
* suppresses inclusion of an attribute mapped for eager fetching.
* The effect of this call may be overridden by subsequent
* invocations of {@link #addAttributeNode} or {@link #addSubgraph}.
* @param attribute attribute
* @since 3.2
*/
public void removeAttributeNode(Attribute<? super T, ?> attribute);

/**
* Remove all attribute nodes of the given attribute types.
* When this graph is interpreted as a load graph, this operation
* suppresses inclusion of attributes mapped for eager fetching.
* The effect of this call may be overridden by subsequent
* invocations of {@link #addAttributeNode} or {@link #addSubgraph}.
* @since 3.2
*/
public void removeAttributeNodes(Attribute.PersistentAttributeType nodeTypes);

/**
* Add one or more attribute nodes to the entity graph.
*
Expand Down
Loading