From 4fb5e861cc24c63eb35082976fbe82518a0de342 Mon Sep 17 00:00:00 2001 From: Gavin King Date: Fri, 18 Oct 2024 14:33:51 +0200 Subject: [PATCH] initial proposal for a stateless EntityAgent for #374 Signed-off-by: Gavin King --- .../java/jakarta/persistence/EntityAgent.java | 262 +++++++++ .../jakarta/persistence/EntityHandler.java | 506 ++++++++++++++++++ .../jakarta/persistence/EntityManager.java | 498 +---------------- .../persistence/EntityManagerFactory.java | 31 ++ .../java/jakarta/persistence/PostDelete.java | 33 ++ .../java/jakarta/persistence/PostInsert.java | 33 ++ .../java/jakarta/persistence/PostUpsert.java | 33 ++ .../java/jakarta/persistence/PreDelete.java | 33 ++ .../java/jakarta/persistence/PreInsert.java | 33 ++ .../java/jakarta/persistence/PreUpsert.java | 33 ++ 10 files changed, 1009 insertions(+), 486 deletions(-) create mode 100644 api/src/main/java/jakarta/persistence/EntityAgent.java create mode 100644 api/src/main/java/jakarta/persistence/EntityHandler.java create mode 100644 api/src/main/java/jakarta/persistence/PostDelete.java create mode 100644 api/src/main/java/jakarta/persistence/PostInsert.java create mode 100644 api/src/main/java/jakarta/persistence/PostUpsert.java create mode 100644 api/src/main/java/jakarta/persistence/PreDelete.java create mode 100644 api/src/main/java/jakarta/persistence/PreInsert.java create mode 100644 api/src/main/java/jakarta/persistence/PreUpsert.java diff --git a/api/src/main/java/jakarta/persistence/EntityAgent.java b/api/src/main/java/jakarta/persistence/EntityAgent.java new file mode 100644 index 00000000..656d088c --- /dev/null +++ b/api/src/main/java/jakarta/persistence/EntityAgent.java @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2008, 2023 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 - 4.0 + +package jakarta.persistence; + +import java.util.List; + +/** + * Interface enabling more direct control over interaction with the + * database than what is possible with {@link EntityManager}. + * + *

An instance of {@code EntityAgent} must be obtained from + * an {@link EntityManagerFactory}, and is able to manage + * persistence of entities belonging to the associated persistence + * unit. + * + *

An {@code EntityAgent} has no associated persistence context, + * and works only with detached entity instances. When a method of + * this interface is called, any necessary interaction with the + * database happens immediately and synchronously. In particular, + * {@linkplain #update update} is an explicit operation. Since + * there's no {@linkplain EntityManager#flush flush operation}, + * and since the entities themselves are detached, modifications to + * the entities are never automatically detected and made persistent. + * + * @since 4.0 + * + * @see EntityManager + */ +public interface EntityAgent extends EntityHandler { + + /** + * Insert a record. + *

+ * If the entity {@link Id} field is declared to be generated, + * for example, if it is annotated {@link GeneratedValue}, the + * id is generated and assigned to the given instance. + *

+ *

+ * + * @param entity a new or removed entity instance + * + * @return The identifier of the inserted entity + * + * @throws IllegalArgumentException is the given instance is + * determined to not be new or removed + */ + Object insert(Object entity); + + /** + * Insert every record in the given list. + * + * @param entities The entities to be inserted. + * + * @see #insert(Object) + */ + void insertMultiple(List entities); + + /** + * Update a record. + *

+ *

    + *
  • The {@link jakarta.persistence.PreUpdate} callback is + * triggered. + *
  • The {@link jakarta.persistence.PostUpdate} callback is + * triggered if the operation is successful. + *
+ * + * @param entity a detached entity instance + * + * @throws IllegalArgumentException if the given instance is + * determined to not be detached + */ + void update(Object entity); + + /** + * Update every record in the given list. + * + * @param entities The entities to be updated. + * + * @see #update(Object) + */ + void updateMultiple(List entities); + + /** + * Delete a record. + *

+ *

    + *
  • The {@link jakarta.persistence.PreDelete} callback is + * triggered. + *
  • The {@link jakarta.persistence.PostDelete} callback is + * triggered if the operation is successful. + *
+ * + * @param entity a detached entity instance + * + * @throws IllegalArgumentException if the given instance is + * determined to not be detached + */ + void delete(Object entity); + + /** + * Delete every record in the given list. + * + * @param entities The entities to be deleted. + * + * @see #delete(Object) + */ + void deleteMultiple(List entities); + + /** + * Perform an upsert, that is, to insert the record if it does + * not exist, or update it if it already exists. + *

+ * This method never performs id generation, and does not accept + * an entity instance with a null identifier. When id generation + * is required, use {@link #insert(Object)}. + *

+ * On the other hand, {@code upsert()} does accept an entity + * instance with an assigned identifier value, even if the entity + * {@link Id} field is declared to be generated, for example, if + * it is annotated {@link GeneratedValue}. Thus, this method may + * be used to import data from an external source. + *

+ *

    + *
  • The {@link jakarta.persistence.PreUpsert} callback is + * triggered. + *
  • The {@link jakarta.persistence.PostUpsert} callback is + * triggered if the operation is successful. + *
+ * + * @param entity a detached entity instance, or a new instance + * with an assigned identifier + * @throws IllegalArgumentException is the entity has a null id + */ + void upsert(Object entity); + + /** + * Upsert every record in the given list. + * + * @param entities The entities to be inserted or updated. + * + * @see #upsert(Object) + */ + void upsertMultiple(List entities); + + /** + * Retrieve a record. + * + * @param entityClass The class of the entity to retrieve + * @param id The id of the entity to retrieve + * + * @return a detached entity instance + */ + T get(Class entityClass, Object id); + + /** + * Retrieve a record, obtaining the specified lock mode. + * + * @param entityClass The class of the entity to retrieve + * @param id The id of the entity to retrieve + * @param lockMode The lock mode to apply to the entity + * + * @return a detached entity instance + */ + T get(Class entityClass, Object id, LockModeType lockMode); + + /** + * Retrieve a record, fetching associations specified by the + * given {@link EntityGraph}. + * + * @param graph The {@link EntityGraph} + * @param graphSemantic a {@link GraphSemantic} specifying + * how the graph should be interpreted + * @param id The id of the entity to retrieve + * + * @return a detached entity instance + * + * @since 6.3 + */ + T get(EntityGraph graph, Object id); + + /** + * Retrieve a record, fetching associations specified by the + * given {@linkplain EntityGraph load graph}, and obtaining + * the specified {@link LockModeType lock mode}. + * + * @param graph The {@linkplain EntityGraph load graph} + * @param id The id of the entity to retrieve + * @param lockMode The lock mode to apply to the entity + * + * @return a detached entity instance + */ + T get(EntityGraph graph, Object id, LockModeType lockMode); + + /** + * Retrieve multiple rows, returning entity instances in a + * list where the position of an instance in the list matches + * the position of its identifier in the given array, and the + * list contains a null value if there is no persistent + * instance matching a given identifier. + * + * @param entityClass The class of the entity to retrieve + * @param ids The ids of the entities to retrieve + * @return an ordered list of detached entity instances, with + * null elements representing missing entities + */ + List getMultiple(Class entityClass, List ids); + + /** + * Refresh the entity instance state from the database. + * + * @param entity The entity to be refreshed. + */ + void refresh(Object entity); + + /** + * Refresh multiple entities. + * + * @param entities The entities to be refreshed. + * + * @see #refresh(Object) + */ + void refreshMultiple(List entities); + + /** + * Refresh the entity instance state from the database. + * + * @param entity The entity to be refreshed. + * @param lockMode The LockMode to be applied. + */ + void refresh(Object entity, LockModeType lockMode); + + /** + * Fetch an association or collection that's configured for lazy loading. + *
+     * Book book = agent.get(Book.class, isbn);  // book is immediately detached
+     * agent.fetch(book.getAuthors());           // fetch the associated authors
+     * book.getAuthors().forEach(author -> ... );  // iterate the collection
+     * 
+ * + * @param association a {@linkplain FetchType#LAZY lazy} association + */ + void fetch(Object association); +} diff --git a/api/src/main/java/jakarta/persistence/EntityHandler.java b/api/src/main/java/jakarta/persistence/EntityHandler.java new file mode 100644 index 00000000..35f1690e --- /dev/null +++ b/api/src/main/java/jakarta/persistence/EntityHandler.java @@ -0,0 +1,506 @@ +/* + * Copyright (c) 2008, 2023 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 - 4.0 + +package jakarta.persistence; + +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaDelete; +import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.CriteriaSelect; +import jakarta.persistence.criteria.CriteriaUpdate; +import jakarta.persistence.metamodel.Metamodel; + +import java.util.List; +import java.util.Map; + +/** + * Declares operations common to {@link EntityManager} + * and {@link EntityAgent}. + * + * @since 4.0 + */ +public interface EntityHandler extends AutoCloseable { + + /** + * Set the default {@linkplain CacheRetrieveMode cache retrieval + * mode} for this {@code EntityHandler}. + * @param cacheRetrieveMode cache retrieval mode + * @since 3.2 + */ + void setCacheRetrieveMode(CacheRetrieveMode cacheRetrieveMode); + + /** + * Set the default {@linkplain CacheStoreMode cache storage mode} + * for this {@code EntityHandler}. + * @param cacheStoreMode cache storage mode + * @since 3.2 + */ + void setCacheStoreMode(CacheStoreMode cacheStoreMode); + + /** + * The cache retrieval mode for this {@code EntityHandler}. + * @since 3.2 + */ + CacheRetrieveMode getCacheRetrieveMode(); + + /** + * The cache storage mode for this {@code EntityHandler}. + * @since 3.2 + */ + CacheStoreMode getCacheStoreMode(); + + /** + * Set an {@code EntityHandler}-scoped property or hint. + * If a vendor-specific property or hint is not recognized, it is + * silently ignored. + * @param propertyName name of the property or hint + * @param value value for the property or hint + * @throws IllegalArgumentException if the property or hint name + * is recognized by the implementation, but the second + * argument is not valid value + * @since 2.0 + */ + void setProperty(String propertyName, Object value); + + /** + * The properties and hints and their associated values which + * are in effect for this {@code EntityHandler}. Modifying the + * contents of the returned map does not change the configuration + * in effect. + * @return a map of properties and hints currently in effect + * @since 2.0 + */ + Map getProperties(); + + /** + * Create an instance of {@link Query} for executing a + * Jakarta Persistence query language statement. + * @param qlString a Jakarta Persistence query string + * @return the new query instance + * @throws IllegalArgumentException if the query string is + * found to be invalid + */ + Query createQuery(String qlString); + + /** + * Create an instance of {@link TypedQuery} for executing a + * criteria query. + * @param criteriaQuery a criteria query object + * @return the new query instance + * @throws IllegalArgumentException if the criteria query is + * found to be invalid + * @since 2.0 + */ + TypedQuery createQuery(CriteriaQuery criteriaQuery); + + /** + * Create an instance of {@link TypedQuery} for executing a + * criteria query, which may be a union or intersection of + * top-level queries. + * @param selectQuery a criteria query object + * @return the new query instance + * @throws IllegalArgumentException if the criteria query is + * found to be invalid + * @since 3.2 + */ + TypedQuery createQuery(CriteriaSelect selectQuery); + + /** + * Create an instance of {@link Query} for executing a criteria + * update query. + * @param updateQuery a criteria update query object + * @return the new query instance + * @throws IllegalArgumentException if the update query is + * found to be invalid + * @since 2.1 + */ + Query createQuery(CriteriaUpdate updateQuery); + + /** + * Create an instance of {@link Query} for executing a criteria + * delete query. + * @param deleteQuery a criteria delete query object + * @return the new query instance + * @throws IllegalArgumentException if the delete query is + * found to be invalid + * @since 2.1 + */ + Query createQuery(CriteriaDelete deleteQuery); + + /** + * Create an instance of {@link TypedQuery} for executing a + * Jakarta Persistence query language statement. + * The select list of the query must contain only a single + * item, which must be assignable to the type specified by + * the {@code resultClass} argument. + * @param qlString a Jakarta Persistence query string + * @param resultClass the type of the query result + * @return the new query instance + * @throws IllegalArgumentException if the query string is + * found to be invalid or if the query result is + * found to not be assignable to the specified type + * @since 2.0 + */ + TypedQuery createQuery(String qlString, Class resultClass); + + /** + * Create an instance of {@link Query} for executing a named + * query written in the Jakarta Persistence query language or + * in native SQL. + * @param name the name of a query defined in metadata + * @return the new query instance + * @throws IllegalArgumentException if a query has not been + * defined with the given name or if the query string is + * found to be invalid + * @see NamedQuery + * @see NamedNativeQuery + */ + Query createNamedQuery(String name); + + /** + * Create an instance of {@link TypedQuery} for executing a + * Jakarta Persistence query language named query. + * The select list of the query must contain only a single + * item, which must be assignable to the type specified by + * the {@code resultClass} argument. + * @param name the name of a query defined in metadata + * @param resultClass the type of the query result + * @return the new query instance + * @throws IllegalArgumentException if a query has not been + * defined with the given name or if the query string is + * found to be invalid or if the query result is found to + * not be assignable to the specified type + * @since 2.0 + */ + TypedQuery createNamedQuery(String name, Class resultClass); + + /** + * Create an instance of {@link TypedQuery} for executing a + * named query written in the Jakarta Persistence query + * language or in native SQL. + * @param reference a reference to the query defined in metadata + * @return the new query instance + * @throws IllegalArgumentException if a query has not been + * defined, or if the query string is found to be + * invalid, or if the query result is found to not be + * assignable to the specified type + * @see EntityManagerFactory#getNamedQueries(Class) + * @see NamedQuery + * @see NamedNativeQuery + */ + TypedQuery createQuery(TypedQueryReference reference); + + /** + * Create an instance of {@link Query} for executing a native + * SQL statement, e.g., for update or delete. + * + *

If the query is not an update or delete query, query + * execution will result in each row of the SQL result being + * returned as a result of type {@code Object[]} (or a result + * of type {@code Object} if there is only one column in the + * select list.) Column values are returned in the order of + * their occurrence in the select list and default JDBC type + * mappings are applied. + * @param sqlString a native SQL query string + * @return the new query instance + */ + Query createNativeQuery(String sqlString); + + /** + * Create an instance of {@link Query} for executing a native + * SQL query. + * + *

In the next release of this API, the return type of this + * method will change to {@code TypedQuery}. + * @param sqlString a native SQL query string + * @param resultClass the type of the query result + * @return the new query instance + */ + Query createNativeQuery(String sqlString, Class resultClass); + + /** + * Create an instance of {@link Query} for executing + * a native SQL query. + * @param sqlString a native SQL query string + * @param resultSetMapping the name of the result set mapping + * @return the new query instance + */ + Query createNativeQuery(String sqlString, String resultSetMapping); + + /** + * Create an instance of {@link StoredProcedureQuery} for executing + * a stored procedure in the database. + *

Parameters must be registered before the stored procedure can + * be executed. + *

If the stored procedure returns one or more result sets, any + * result set is returned as a list of type {@code Object[]}. + * @param name name assigned to the stored procedure query in + * metadata + * @return the new stored procedure query instance + * @throws IllegalArgumentException if no query has been defined + * with the given name + * @since 2.1 + */ + StoredProcedureQuery createNamedStoredProcedureQuery(String name); + + /** + * Create an instance of {@link StoredProcedureQuery} for executing a + * stored procedure in the database. + *

Parameters must be registered before the stored procedure can + * be executed. + *

If the stored procedure returns one or more result sets, any + * result set is returned as a list of type {@code Object[]}. + * @param procedureName name of the stored procedure in the database + * @return the new stored procedure query instance + * @throws IllegalArgumentException if a stored procedure of the + * given name does not exist (or if query execution will + * fail) + * @since 2.1 + */ + StoredProcedureQuery createStoredProcedureQuery(String procedureName); + + /** + * Create an instance of {@link StoredProcedureQuery} for executing + * a stored procedure in the database. + *

Parameters must be registered before the stored procedure can + * be executed. + *

The {@code resultClass} arguments must be specified in the + * order in which the result sets is returned by the stored procedure + * invocation. + * @param procedureName name of the stored procedure in the database + * @param resultClasses classes to which the result sets + * produced by the stored procedure are to be mapped + * @return the new stored procedure query instance + * @throws IllegalArgumentException if a stored procedure of the + * given name does not exist (or if query execution will + * fail) + * @since 2.1 + */ + StoredProcedureQuery createStoredProcedureQuery( + String procedureName, Class... resultClasses); + + /** + * Create an instance of {@link StoredProcedureQuery} for executing + * a stored procedure in the database. + *

Parameters must be registered before the stored procedure can + * be executed. + *

The {@code resultSetMapping} arguments must be specified in + * the order in which the result sets is returned by the stored + * procedure invocation. + * @param procedureName name of the stored procedure in the + * database + * @param resultSetMappings the names of the result set mappings + * to be used in mapping result sets + * returned by the stored procedure + * @return the new stored procedure query instance + * @throws IllegalArgumentException if a stored procedure or + * result set mapping of the given name does not exist + * (or the query execution will fail) + */ + StoredProcedureQuery createStoredProcedureQuery( + String procedureName, String... resultSetMappings); + + /** + * Indicate to the entity manager that a JTA transaction is + * active and join the persistence context to it. + *

This method should be called on a JTA application + * managed entity manager that was created outside the scope + * of the active transaction or on an entity manager of type + * {@link SynchronizationType#UNSYNCHRONIZED} to associate + * it with the current JTA transaction. + * @throws TransactionRequiredException if there is no active + * transaction + */ + void joinTransaction(); + + /** + * Determine whether the entity manager is joined to the + * current transaction. Returns false if the entity manager + * is not joined to the current transaction or if no + * transaction is active. + * @return boolean + * @since 2.1 + */ + boolean isJoinedToTransaction(); + + /** + * Return an object of the specified type to allow access to + * a provider-specific API. If the provider implementation + * of {@code EntityHandler} does not support the given type, + * the {@link PersistenceException} is thrown. + * @param cls the class of the object to be returned. + * This is usually either the underlying class + * implementing {@code EntityHandler} or an + * interface it implements. + * @return an instance of the specified class + * @throws PersistenceException if the provider does not + * support the given type + * @since 2.0 + */ + T unwrap(Class cls); + + /** + * Return the underlying provider object for the + * {@link EntityHandler}, if available. The result of this + * method is implementation-specific. + *

The {@code unwrap} method is to be preferred for new + * applications. + * @return the underlying provider object + */ + Object getDelegate(); + + /** + * Close an application-managed {@code EntityHandler}. + *

After invocation of {@code close()}, every method of + * the {@code EntityHandler} instance and of any instance + * of {@link Query}, {@link TypedQuery}, or + * {@link StoredProcedureQuery} obtained from it throws + * the {@link IllegalStateException}, except for + * {@link #getProperties()}, {@link #getTransaction()}, + * and {@link #isOpen()} (which returns false). + *

If this method is called when the entity manager is + * joined to an active transaction, the persistence context + * remains managed until the transaction completes. + * @throws IllegalStateException if the entity manager is + * container-managed + */ + void close(); + + /** + * Determine whether the {@code EntityHandler} is open. + * @return true until the {@code EntityHandler} has been closed + */ + boolean isOpen(); + + /** + * Return the resource-level {@link EntityTransaction} object. + * The {@code EntityTransaction} instance may be used serially + * to begin and commit multiple transactions. + * @return EntityTransaction instance + * @throws IllegalStateException if invoked on a JTA entity + * manager + */ + EntityTransaction getTransaction(); + + /** + * The {@linkplain EntityManagerFactory entity manager factory} + * which created this entity manager. + * @return the {@link EntityManagerFactory} + * @throws IllegalStateException if the entity manager has + * been closed + * @since 2.0 + */ + EntityManagerFactory getEntityManagerFactory(); + + /** + * Obtain an instance of {@link CriteriaBuilder} which may be + * used to construct {@link CriteriaQuery} objects. + * @return an instance of {@link CriteriaBuilder} + * @throws IllegalStateException if the entity manager has + * been closed + * @see EntityManagerFactory#getCriteriaBuilder() + * @since 2.0 + */ + CriteriaBuilder getCriteriaBuilder(); + + /** + * Obtain an instance of the {@link Metamodel} interface which + * provides access to metamodel objects describing the managed + * types belonging to the persistence unit. + * @return an instance of {@link Metamodel} + * @throws IllegalStateException if the entity manager has + * been closed + * @since 2.0 + */ + Metamodel getMetamodel(); + + /** + * Create a new mutable {@link EntityGraph}, allowing dynamic + * definition of an entity graph. + * @param rootType class of entity graph + * @return entity graph + * @since 2.1 + */ + EntityGraph createEntityGraph(Class rootType); + + /** + * Obtain a mutable copy of a named {@link EntityGraph}, or + * return null if there is no entity graph with the given + * name. + * @param graphName name of an entity graph + * @return entity graph + * @since 2.1 + */ + EntityGraph createEntityGraph(String graphName); + + /** + * Obtain a named {@link EntityGraph}. The returned instance + * of {@code EntityGraph} should be considered immutable. + * @param graphName name of an existing entity graph + * @return named entity graph + * @throws IllegalArgumentException if there is no entity + * of graph with the given name + * @since 2.1 + */ + EntityGraph getEntityGraph(String graphName); + + /** + * Return all named {@link EntityGraph}s that are defined for + * the given entity class type. + * @param entityClass entity class + * @return list of all entity graphs defined for the entity + * @throws IllegalArgumentException if the class is not an entity + * @since 2.1 + */ + List> getEntityGraphs(Class entityClass); + + /** + * Execute the given action using the database connection underlying this + * {@code EntityHandler}. Usually, the connection is a JDBC connection, but a + * provider might support some other native connection type, and is not required + * to support {@code java.sql.Connection}. If this {@code EntityHandler} is + * associated with a transaction, the action is executed in the context of the + * transaction. The given action should close any resources it creates, but should + * not close the connection itself, nor commit or roll back the transaction. If + * the given action throws an exception, the persistence provider must mark the + * transaction for rollback. + * @param action the action + * @param the connection type, usually {@code java.sql.Connection} + * @throws PersistenceException wrapping the checked {@link Exception} thrown by + * {@link ConnectionConsumer#accept}, if any + * @since 3.2 + */ + void runWithConnection(ConnectionConsumer action); + + /** + * Call the given function and return its result using the database connection + * underlying this {@code EntityHandler}. Usually, the connection is a JDBC + * connection, but a provider might support some other native connection type, + * and is not required to support {@code java.sql.Connection}. If this + * {@code EntityHandler} is associated with a transaction, the function is + * executed in the context of the transaction. The given function should close + * any resources it creates, but should not close the connection itself, nor + * commit or roll back the transaction. If the given action throws an exception, + * the persistence provider must mark the transaction for rollback. + * @param function the function + * @param the connection type, usually {@code java.sql.Connection} + * @param the type of result returned by the function + * @return the value returned by {@link ConnectionFunction#apply}. + * @throws PersistenceException wrapping the checked {@link Exception} thrown by + * {@link ConnectionFunction#apply}, if any + * @since 3.2 + */ + T callWithConnection(ConnectionFunction function); +} diff --git a/api/src/main/java/jakarta/persistence/EntityManager.java b/api/src/main/java/jakarta/persistence/EntityManager.java index 80b41a19..c226dd28 100644 --- a/api/src/main/java/jakarta/persistence/EntityManager.java +++ b/api/src/main/java/jakarta/persistence/EntityManager.java @@ -11,6 +11,7 @@ */ // Contributors: +// Gavin King - 4.0 // Gavin King - 3.2 // Linda DeMichiel - 2.1 // Linda DeMichiel - 2.0 @@ -19,14 +20,8 @@ package jakarta.persistence; import java.util.Map; -import java.util.List; -import jakarta.persistence.criteria.CriteriaSelect; -import jakarta.persistence.metamodel.Metamodel; -import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; -import jakarta.persistence.criteria.CriteriaUpdate; -import jakarta.persistence.criteria.CriteriaDelete; /** * Interface used to interact with the persistence context. @@ -65,7 +60,7 @@ * {@linkplain PersistenceUnitTransactionType#RESOURCE_LOCAL * resource local} transaction management, transactions must * be managed using the {@link EntityTransaction} obtained by - * calling {@link #getTransaction()}. + * calling {@link EntityHandler#getTransaction getTransaction()}. * *

A complete idiom for custom application management of * the {@link EntityManager} and its associated resource-local @@ -119,11 +114,11 @@ * the lifecycle state of individual entity instances. The client * may {@linkplain #persist} and {@linkplain #remove} instances, * {@linkplain #find(Class, Object) find} entities by their primary - * key, and execute {@linkplain #createQuery(String) queries} which - * range over entity types. An entity may be disassociated from - * the persistence context by calling {@link #detach}, and a - * persistence context may be completely cleared, detaching all - * its entities, by calling {@link #clear()}. + * key, and execute {@linkplain EntityHandler#createQuery(String) + * queries} which range over entity types. A given entity may be + * disassociated from the persistence context by calling + * {@link #detach}, and a persistence context may be completely + * cleared, detaching all its entities, by calling {@link #clear()}. * *

The client may also make changes to the state of an entity * instance by mutating the entity directly, or it may request @@ -164,9 +159,9 @@ * type of lock. * *

Interaction of the persistence context (or first-level cache) - * with the second-level cache, if any, may be controlled by - * calling {@link #setCacheRetrieveMode(CacheRetrieveMode)} and - * {@link #setCacheStoreMode(CacheStoreMode)}. + * with the second-level cache, if any, may be controlled by calling + * {@link EntityHandler#setCacheRetrieveMode(CacheRetrieveMode)} and + * {@link EntityHandler#setCacheStoreMode(CacheStoreMode)}. * *

Some operations accept one or more built-in and vendor-specific * options: @@ -186,10 +181,11 @@ * @see PersistenceContext * @see StoredProcedureQuery * @see EntityManagerFactory + * @see EntityAgent * * @since 1.0 */ -public interface EntityManager extends AutoCloseable { +public interface EntityManager extends EntityHandler { /** * Make a new entity instance managed and persistent, resulting in @@ -933,474 +929,4 @@ void refresh(Object entity, */ LockModeType getLockMode(Object entity); - /** - * Set the default {@linkplain CacheRetrieveMode cache retrieval - * mode} for this persistence context. - * @param cacheRetrieveMode cache retrieval mode - * @since 3.2 - */ - void setCacheRetrieveMode(CacheRetrieveMode cacheRetrieveMode); - - /** - * Set the default {@linkplain CacheStoreMode cache storage mode} - * for this persistence context. - * @param cacheStoreMode cache storage mode - * @since 3.2 - */ - void setCacheStoreMode(CacheStoreMode cacheStoreMode); - - /** - * The cache retrieval mode for this persistence context. - * @since 3.2 - */ - CacheRetrieveMode getCacheRetrieveMode(); - - /** - * The cache storage mode for this persistence context. - * @since 3.2 - */ - CacheStoreMode getCacheStoreMode(); - - /** - * Set an entity manager property or hint. - * If a vendor-specific property or hint is not recognized, it is - * silently ignored. - * @param propertyName name of the property or hint - * @param value value for the property or hint - * @throws IllegalArgumentException if the property or hint name - * is recognized by the implementation, but the second - * argument is not valid value - * @since 2.0 - */ - void setProperty(String propertyName, Object value); - - /** - * The properties and hints and their associated values which are - * in effect for this entity manager. Modifying the contents of - * the returned map does not change the configuration in effect. - * @return a map of properties and hints currently in effect - * @since 2.0 - */ - Map getProperties(); - - /** - * Create an instance of {@link Query} for executing a - * Jakarta Persistence query language statement. - * @param qlString a Jakarta Persistence query string - * @return the new query instance - * @throws IllegalArgumentException if the query string is - * found to be invalid - */ - Query createQuery(String qlString); - - /** - * Create an instance of {@link TypedQuery} for executing a - * criteria query. - * @param criteriaQuery a criteria query object - * @return the new query instance - * @throws IllegalArgumentException if the criteria query is - * found to be invalid - * @since 2.0 - */ - TypedQuery createQuery(CriteriaQuery criteriaQuery); - - /** - * Create an instance of {@link TypedQuery} for executing a - * criteria query, which may be a union or intersection of - * top-level queries. - * @param selectQuery a criteria query object - * @return the new query instance - * @throws IllegalArgumentException if the criteria query is - * found to be invalid - * @since 3.2 - */ - TypedQuery createQuery(CriteriaSelect selectQuery); - - /** - * Create an instance of {@link Query} for executing a criteria - * update query. - * @param updateQuery a criteria update query object - * @return the new query instance - * @throws IllegalArgumentException if the update query is - * found to be invalid - * @since 2.1 - */ - Query createQuery(CriteriaUpdate updateQuery); - - /** - * Create an instance of {@link Query} for executing a criteria - * delete query. - * @param deleteQuery a criteria delete query object - * @return the new query instance - * @throws IllegalArgumentException if the delete query is - * found to be invalid - * @since 2.1 - */ - Query createQuery(CriteriaDelete deleteQuery); - - /** - * Create an instance of {@link TypedQuery} for executing a - * Jakarta Persistence query language statement. - * The select list of the query must contain only a single - * item, which must be assignable to the type specified by - * the {@code resultClass} argument. - * @param qlString a Jakarta Persistence query string - * @param resultClass the type of the query result - * @return the new query instance - * @throws IllegalArgumentException if the query string is - * found to be invalid or if the query result is - * found to not be assignable to the specified type - * @since 2.0 - */ - TypedQuery createQuery(String qlString, Class resultClass); - - /** - * Create an instance of {@link Query} for executing a named - * query written in the Jakarta Persistence query language or - * in native SQL. - * @param name the name of a query defined in metadata - * @return the new query instance - * @throws IllegalArgumentException if a query has not been - * defined with the given name or if the query string is - * found to be invalid - * @see NamedQuery - * @see NamedNativeQuery - */ - Query createNamedQuery(String name); - - /** - * Create an instance of {@link TypedQuery} for executing a - * Jakarta Persistence query language named query. - * The select list of the query must contain only a single - * item, which must be assignable to the type specified by - * the {@code resultClass} argument. - * @param name the name of a query defined in metadata - * @param resultClass the type of the query result - * @return the new query instance - * @throws IllegalArgumentException if a query has not been - * defined with the given name or if the query string is - * found to be invalid or if the query result is found to - * not be assignable to the specified type - * @since 2.0 - */ - TypedQuery createNamedQuery(String name, Class resultClass); - - /** - * Create an instance of {@link TypedQuery} for executing a - * named query written in the Jakarta Persistence query - * language or in native SQL. - * @param reference a reference to the query defined in metadata - * @return the new query instance - * @throws IllegalArgumentException if a query has not been - * defined, or if the query string is found to be - * invalid, or if the query result is found to not be - * assignable to the specified type - * @see EntityManagerFactory#getNamedQueries(Class) - * @see NamedQuery - * @see NamedNativeQuery - */ - TypedQuery createQuery(TypedQueryReference reference); - - /** - * Create an instance of {@link Query} for executing a native - * SQL statement, e.g., for update or delete. - * - *

If the query is not an update or delete query, query - * execution will result in each row of the SQL result being - * returned as a result of type {@code Object[]} (or a result - * of type {@code Object} if there is only one column in the - * select list.) Column values are returned in the order of - * their occurrence in the select list and default JDBC type - * mappings are applied. - * @param sqlString a native SQL query string - * @return the new query instance - */ - Query createNativeQuery(String sqlString); - - /** - * Create an instance of {@link Query} for executing a native - * SQL query. - * - *

In the next release of this API, the return type of this - * method will change to {@code TypedQuery}. - * @param sqlString a native SQL query string - * @param resultClass the type of the query result - * @return the new query instance - */ - Query createNativeQuery(String sqlString, Class resultClass); - - /** - * Create an instance of {@link Query} for executing - * a native SQL query. - * @param sqlString a native SQL query string - * @param resultSetMapping the name of the result set mapping - * @return the new query instance - */ - Query createNativeQuery(String sqlString, String resultSetMapping); - - /** - * Create an instance of {@link StoredProcedureQuery} for executing - * a stored procedure in the database. - *

Parameters must be registered before the stored procedure can - * be executed. - *

If the stored procedure returns one or more result sets, any - * result set is returned as a list of type {@code Object[]}. - * @param name name assigned to the stored procedure query in - * metadata - * @return the new stored procedure query instance - * @throws IllegalArgumentException if no query has been defined - * with the given name - * @since 2.1 - */ - StoredProcedureQuery createNamedStoredProcedureQuery(String name); - - /** - * Create an instance of {@link StoredProcedureQuery} for executing a - * stored procedure in the database. - *

Parameters must be registered before the stored procedure can - * be executed. - *

If the stored procedure returns one or more result sets, any - * result set is returned as a list of type {@code Object[]}. - * @param procedureName name of the stored procedure in the database - * @return the new stored procedure query instance - * @throws IllegalArgumentException if a stored procedure of the - * given name does not exist (or if query execution will - * fail) - * @since 2.1 - */ - StoredProcedureQuery createStoredProcedureQuery(String procedureName); - - /** - * Create an instance of {@link StoredProcedureQuery} for executing - * a stored procedure in the database. - *

Parameters must be registered before the stored procedure can - * be executed. - *

The {@code resultClass} arguments must be specified in the - * order in which the result sets is returned by the stored procedure - * invocation. - * @param procedureName name of the stored procedure in the database - * @param resultClasses classes to which the result sets - * produced by the stored procedure are to be mapped - * @return the new stored procedure query instance - * @throws IllegalArgumentException if a stored procedure of the - * given name does not exist (or if query execution will - * fail) - * @since 2.1 - */ - StoredProcedureQuery createStoredProcedureQuery( - String procedureName, Class... resultClasses); - - /** - * Create an instance of {@link StoredProcedureQuery} for executing - * a stored procedure in the database. - *

Parameters must be registered before the stored procedure can - * be executed. - *

The {@code resultSetMapping} arguments must be specified in - * the order in which the result sets is returned by the stored - * procedure invocation. - * @param procedureName name of the stored procedure in the - * database - * @param resultSetMappings the names of the result set mappings - * to be used in mapping result sets - * returned by the stored procedure - * @return the new stored procedure query instance - * @throws IllegalArgumentException if a stored procedure or - * result set mapping of the given name does not exist - * (or the query execution will fail) - */ - StoredProcedureQuery createStoredProcedureQuery( - String procedureName, String... resultSetMappings); - - /** - * Indicate to the entity manager that a JTA transaction is - * active and join the persistence context to it. - *

This method should be called on a JTA application - * managed entity manager that was created outside the scope - * of the active transaction or on an entity manager of type - * {@link SynchronizationType#UNSYNCHRONIZED} to associate - * it with the current JTA transaction. - * @throws TransactionRequiredException if there is no active - * transaction - */ - void joinTransaction(); - - /** - * Determine whether the entity manager is joined to the - * current transaction. Returns false if the entity manager - * is not joined to the current transaction or if no - * transaction is active. - * @return boolean - * @since 2.1 - */ - boolean isJoinedToTransaction(); - - /** - * Return an object of the specified type to allow access to - * a provider-specific API. If the provider implementation - * of {@code EntityManager} does not support the given type, - * the {@link PersistenceException} is thrown. - * @param cls the class of the object to be returned. - * This is usually either the underlying class - * implementing {@code EntityManager} or an - * interface it implements. - * @return an instance of the specified class - * @throws PersistenceException if the provider does not - * support the given type - * @since 2.0 - */ - T unwrap(Class cls); - - /** - * Return the underlying provider object for the - * {@link EntityManager}, if available. The result of this - * method is implementation-specific. - *

The {@code unwrap} method is to be preferred for new - * applications. - * @return the underlying provider object - */ - Object getDelegate(); - - /** - * Close an application-managed entity manager. - *

After invocation of {@code close()}, every method of - * the {@code EntityManager} instance and of any instance - * of {@link Query}, {@link TypedQuery}, or - * {@link StoredProcedureQuery} obtained from it throws - * the {@link IllegalStateException}, except for - * {@link #getProperties()}, {@link #getTransaction()}, - * and {@link #isOpen()} (which returns false). - *

If this method is called when the entity manager is - * joined to an active transaction, the persistence context - * remains managed until the transaction completes. - * @throws IllegalStateException if the entity manager is - * container-managed - */ - void close(); - - /** - * Determine whether the entity manager is open. - * @return true until the entity manager has been closed - */ - boolean isOpen(); - - /** - * Return the resource-level {@link EntityTransaction} object. - * The {@code EntityTransaction} instance may be used serially - * to begin and commit multiple transactions. - * @return EntityTransaction instance - * @throws IllegalStateException if invoked on a JTA entity - * manager - */ - EntityTransaction getTransaction(); - - /** - * The {@linkplain EntityManagerFactory entity manager factory} - * which created this entity manager. - * @return the {@link EntityManagerFactory} - * @throws IllegalStateException if the entity manager has - * been closed - * @since 2.0 - */ - EntityManagerFactory getEntityManagerFactory(); - - /** - * Obtain an instance of {@link CriteriaBuilder} which may be - * used to construct {@link CriteriaQuery} objects. - * @return an instance of {@link CriteriaBuilder} - * @throws IllegalStateException if the entity manager has - * been closed - * @see EntityManagerFactory#getCriteriaBuilder() - * @since 2.0 - */ - CriteriaBuilder getCriteriaBuilder(); - - /** - * Obtain an instance of the {@link Metamodel} interface which - * provides access to metamodel objects describing the managed - * types belonging to the persistence unit. - * @return an instance of {@link Metamodel} - * @throws IllegalStateException if the entity manager has - * been closed - * @since 2.0 - */ - Metamodel getMetamodel(); - - /** - * Create a new mutable {@link EntityGraph}, allowing dynamic - * definition of an entity graph. - * @param rootType class of entity graph - * @return entity graph - * @since 2.1 - */ - EntityGraph createEntityGraph(Class rootType); - - /** - * Obtain a mutable copy of a named {@link EntityGraph}, or - * return null if there is no entity graph with the given - * name. - * @param graphName name of an entity graph - * @return entity graph - * @since 2.1 - */ - EntityGraph createEntityGraph(String graphName); - - /** - * Obtain a named {@link EntityGraph}. The returned instance - * of {@code EntityGraph} should be considered immutable. - * @param graphName name of an existing entity graph - * @return named entity graph - * @throws IllegalArgumentException if there is no entity - * of graph with the given name - * @since 2.1 - */ - EntityGraph getEntityGraph(String graphName); - - /** - * Return all named {@link EntityGraph}s that are defined for - * the given entity class type. - * @param entityClass entity class - * @return list of all entity graphs defined for the entity - * @throws IllegalArgumentException if the class is not an entity - * @since 2.1 - */ - List> getEntityGraphs(Class entityClass); - - /** - * Execute the given action using the database connection underlying this - * {@code EntityManager}. Usually, the connection is a JDBC connection, but a - * provider might support some other native connection type, and is not required - * to support {@code java.sql.Connection}. If this {@code EntityManager} is - * associated with a transaction, the action is executed in the context of the - * transaction. The given action should close any resources it creates, but should - * not close the connection itself, nor commit or roll back the transaction. If - * the given action throws an exception, the persistence provider must mark the - * transaction for rollback. - * @param action the action - * @param the connection type, usually {@code java.sql.Connection} - * @throws PersistenceException wrapping the checked {@link Exception} thrown by - * {@link ConnectionConsumer#accept}, if any - * @since 3.2 - */ - void runWithConnection(ConnectionConsumer action); - - /** - * Call the given function and return its result using the database connection - * underlying this {@code EntityManager}. Usually, the connection is a JDBC - * connection, but a provider might support some other native connection type, - * and is not required to support {@code java.sql.Connection}. If this - * {@code EntityManager} is associated with a transaction, the function is - * executed in the context of the transaction. The given function should close - * any resources it creates, but should not close the connection itself, nor - * commit or roll back the transaction. If the given action throws an exception, - * the persistence provider must mark the transaction for rollback. - * @param function the function - * @param the connection type, usually {@code java.sql.Connection} - * @param the type of result returned by the function - * @return the value returned by {@link ConnectionFunction#apply}. - * @throws PersistenceException wrapping the checked {@link Exception} thrown by - * {@link ConnectionFunction#apply}, if any - * @since 3.2 - */ - T callWithConnection(ConnectionFunction function); - } diff --git a/api/src/main/java/jakarta/persistence/EntityManagerFactory.java b/api/src/main/java/jakarta/persistence/EntityManagerFactory.java index 708b34c8..6950771c 100644 --- a/api/src/main/java/jakarta/persistence/EntityManagerFactory.java +++ b/api/src/main/java/jakarta/persistence/EntityManagerFactory.java @@ -11,6 +11,7 @@ */ // Contributors: +// Gavin King - 4.0 // Gavin King - 3.2 // Linda DeMichiel - 2.1 // Linda DeMichiel - 2.0 @@ -185,6 +186,36 @@ public interface EntityManagerFactory extends AutoCloseable { */ EntityManager createEntityManager(SynchronizationType synchronizationType, Map map); + /** + * Create a new application-managed {@link EntityAgent}. This + * method returns a new {@code EntityAgent} instance each time + * it is invoked. + *

The {@link EntityAgent#isOpen} method will return true + * on the returned instance. + * @return entity agent instance + * @throws IllegalStateException if the entity manager factory + * has been closed + * + * @since 4.0 + */ + EntityAgent createEntityAgent(); + + /** + * Create a new application-managed {@link EntityAgent} with + * the given {@link Map} specifying property settings. This + * method returns a new {@code EntityAgent} instance each time + * it is invoked. + *

The {@link EntityAgent#isOpen} method will return true + * on the returned instance. + * @param map properties for entity agent + * @return entity agent instance + * @throws IllegalStateException if the entity manager factory + * has been closed + * + * @since 4.0 + */ + EntityAgent createEntityAgent(Map map); + /** * Return an instance of {@link CriteriaBuilder} which may be used * to construct {@link jakarta.persistence.criteria.CriteriaQuery} diff --git a/api/src/main/java/jakarta/persistence/PostDelete.java b/api/src/main/java/jakarta/persistence/PostDelete.java new file mode 100644 index 00000000..1bee2892 --- /dev/null +++ b/api/src/main/java/jakarta/persistence/PostDelete.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2008, 2023 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 - 4.0 + +package jakarta.persistence; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Specifies a callback method for the corresponding lifecycle event. + * This annotation may be applied to methods of an entity class, a + * mapped superclass, or a callback listener class. + * + * @since 4.0 + */ +@Target({METHOD}) +@Retention(RUNTIME) +public @interface PostDelete {} diff --git a/api/src/main/java/jakarta/persistence/PostInsert.java b/api/src/main/java/jakarta/persistence/PostInsert.java new file mode 100644 index 00000000..f30905c2 --- /dev/null +++ b/api/src/main/java/jakarta/persistence/PostInsert.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2008, 2023 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 - 4.0 + +package jakarta.persistence; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Specifies a callback method for the corresponding lifecycle event. + * This annotation may be applied to methods of an entity class, a + * mapped superclass, or a callback listener class. + * + * @since 4.0 + */ +@Target({METHOD}) +@Retention(RUNTIME) +public @interface PostInsert {} diff --git a/api/src/main/java/jakarta/persistence/PostUpsert.java b/api/src/main/java/jakarta/persistence/PostUpsert.java new file mode 100644 index 00000000..55f125cf --- /dev/null +++ b/api/src/main/java/jakarta/persistence/PostUpsert.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2008, 2023 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 - 4.0 + +package jakarta.persistence; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Specifies a callback method for the corresponding lifecycle event. + * This annotation may be applied to methods of an entity class, a + * mapped superclass, or a callback listener class. + * + * @since 4.0 + */ +@Target({METHOD}) +@Retention(RUNTIME) +public @interface PostUpsert {} diff --git a/api/src/main/java/jakarta/persistence/PreDelete.java b/api/src/main/java/jakarta/persistence/PreDelete.java new file mode 100644 index 00000000..22264931 --- /dev/null +++ b/api/src/main/java/jakarta/persistence/PreDelete.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2008, 2023 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 - 4.0 + +package jakarta.persistence; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Specifies a callback method for the corresponding lifecycle event. + * This annotation may be applied to methods of an entity class, a + * mapped superclass, or a callback listener class. + * + * @since 4.0 + */ +@Target({METHOD}) +@Retention(RUNTIME) +public @interface PreDelete {} diff --git a/api/src/main/java/jakarta/persistence/PreInsert.java b/api/src/main/java/jakarta/persistence/PreInsert.java new file mode 100644 index 00000000..cdf367c5 --- /dev/null +++ b/api/src/main/java/jakarta/persistence/PreInsert.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2008, 2023 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 - 4.0 + +package jakarta.persistence; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Specifies a callback method for the corresponding lifecycle event. + * This annotation may be applied to methods of an entity class, a + * mapped superclass, or a callback listener class. + * + * @since 4.0 + */ +@Target({METHOD}) +@Retention(RUNTIME) +public @interface PreInsert {} diff --git a/api/src/main/java/jakarta/persistence/PreUpsert.java b/api/src/main/java/jakarta/persistence/PreUpsert.java new file mode 100644 index 00000000..c1df2ccb --- /dev/null +++ b/api/src/main/java/jakarta/persistence/PreUpsert.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2008, 2023 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 - 4.0 + +package jakarta.persistence; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Specifies a callback method for the corresponding lifecycle event. + * This annotation may be applied to methods of an entity class, a + * mapped superclass, or a callback listener class. + * + * @since 4.0 + */ +@Target({METHOD}) +@Retention(RUNTIME) +public @interface PreUpsert {}