F.1 Runtime-related contract
The runtime-related contract includes the responsibilities of the container and the responsibilities of the JPA provider.
- Organization of this subsection
(1) Responsibilities of the container
-
Contract related to the transaction scope persistence context
If the transaction scope persistence context is used, the container executes the following processing if the entity manager is not associated with a JTA transaction:
-
The container invokes EntityManagerFactory.createEntityManager in the following cases and creates a new entity manager:
If the entity manager method that uses the transaction scope persistence context is invoked for the first time in a business method within the scope of the JTA transaction
-
After the JTA transaction is concluded (committed or rolled back), the container invokes EntityManager.close to close the entity manager.
Also, if the container satisfies all the following conditions, TransactionRequiredException is thrown:
-
When the transaction scope persistence context is used
-
When the transaction is not active
-
When the application invokes the persist, remove, merge, and refresh methods of EntityManager
-
-
Contract related to the extended persistence context
If the extended persistence context is used, the container executes the following processing:
-
The container invokes EntityManagerFactory.createEntityManager in the following cases and creates a new entity manager:
If the references to the entity manager using the extended persistence context are defined when the Stateful Session Bean instance is created
-
The container invokes EntityManager.close at the following timing and closes the entity manager:
When the Stateful Session Bean that created the entity manager and the Stateful Session Bean that inherited the same persistence context are deleted
-
When a business method of the Stateful Session Bean that uses a container-managed transaction is invoked, if the entity manager is not associated with a JTA transaction, the container associates the entity manager with the JTA transaction and invokes EntityManager.joinTransaction. If another entity manager is already associated with the JTA transaction, the container throws EJBException.
-
When UserTransaction.begin is invoked in a business method of the Stateful Session Bean that uses a bean-managed transaction, the container associates the entity manager with the JTA transaction and invokes EntityManager.joinTransaction. For details on the bean-managed transactions, see 2.7.2 BMT in the uCosminexus Application Server EJB Container Functionality Guide.
-
-
Contract related to the container-managed entity manager
If the application invokes EntityManager.close when the container-managed entity manager is being used, the container throws IllegalStateException.
If the property is specified in @PersistenceContext or in the <persistence-context-ref> tag of the DD, the container uses the EntityManagerFactory.createEntityManager(Map map) method, creates the entity manager, includes the specified property in the map argument, and passes the property to the JPA provider.
-
Automatic connection closing functionality
In Application Server, the connection obtained by the JPA provider with the extension of the Session Bean and Web components sometimes closes automatically by the automatic closing functionality of the container. The automatic connection closing functionality is used to prevent a connection leak.
The connection is subject to being closed automatically if the following conditions are satisfied:
-
A connection obtained by a Stateless Session Bean is closed automatically when returned from a business method.
-
A connection obtained by a Stateful Session Bean is closed automatically when the Stateful Session Bean is destroyed.
-
A connection obtained by a Web component is closed automatically when returned from a service method.
However, even if the above conditions are applicable, if the connection is participating in a JTA transaction, automatic close is reserved until the JTA transaction is committed.
-
(2) Responsibilities of the JPA provider
Whether the entity manager to be used with an application is defined to use the transaction scope persistence context or the extended persistence context, is not transmitted to the JPA provider. The responsibilities of the JPA provider include creating the entity manager when requested by the container and registering Synchronization in the transaction in order to receive the notification about transaction conclusion from the transaction.
-
When the container invokes EntityManagerFactory.createEntityManager, the JPA provider must create a new entity manager and return the created entity manager to the container. If a JTA transaction is active, the JPA provider must register Synchronization in the JTA transaction.
-
When the container invokes EntityManager.joinTransaction, the JPA provider must register Synchronization in the JTA transaction. However, if joinTransaction was invoked previously and Synchronization is already registered in the JTA transaction, nothing need be done.
-
When a JTA transaction is committed, the JPA provider must flush all the changed entity statuses in the database.
-
When a JTA transaction is rolled back, the JPA provider must detach all the managed entities.
-
When the JPA provider throws an exception that causes transaction rollback, the JPA provider must mark the transaction for rollback.
-
When the container invokes EntityManager.close, the JPA provider must release all the allocated resources after all the unresolved transactions related to that entity manager are concluded. If the entity manager is already closed, the JPA provider must throw IllegalStateException.
-
When the container invokes EntityManager.clear, the JPA provider must detach all the managed entities.
(3) javax.transaction.TransactionSynchronizationRegistry interface
The JPA provider can use the TransactionSynchronizationRegistry interface to register Synchronization in a transaction and to mark a transaction for rollback. The TransactionSynchronizationRegistry instance can be looked up with the name java:comp/TransactionSynchronizationRegistry using the JNDI.
The interface definition is as follows:
package javax.transaction; /** * This interface is used from system level components * of Application Server such as the * JPA provider and resource adapters. * Using this interface, you can * register synchronization invoked in a particular order, * register the resource object in the current transaction, * obtain the current transaction context, * obtain the current transaction status, * and mark the current transaction for rollback. * * This interface is implemented by Application Server * as a stateless service object. * The same object can be used from multiple components * in a multi-thread safe manner. * * With default Application Server, the instance implementing this * interface can be looked up with the default name using the JNDI. * The default name is * java:comp/TransactionSynchronizationRegistry. */ public interface TransactionSynchronizationRegistry { /** * When this method is invoked, a unique object expressing the * transaction associated with the current thread is returned. * The hashCode and equals method of this object is overridden * and can be used as the hashmap key. * If the transaction does not exist, null is returned. * * All the objects returned by invoking this method in the same * transaction context of same Application Server have the same * hashCode and the comparison results in the equal method are * true. * * The toString method returns the transaction context information * as a string in an easy-to-read format. * However, the string format returned by toString is not defined. * Also, the compatibility of the toString results between versions * is not guaranteed. * * There is no guarantee that the obtained object can be serialized * and the operations when the object is sent outside JavaVM are * not defined. * * @return Object that uniquely expresses the transaction * associated with the thread when this method is invoked. */ Object getTransactionKey(); /** * The object is added or replaced in the resource map * of the transaction associated with the thread used when this * method is invoked. * The map key must be a class defined on the method invocation * side so that conflict does not occur. * The class used as the key must have the appropriate hashCode * and equals method as the map key. * The map key and value is not evaluated and used by this class. * The general contract of this method is the same as the put * method of Map and the key must be other than null, but the * value can be set as null. * If a value associated with the key already exists, the value * is replaced. * * @param key Entry key of map * @param value Entry value of map * @exception IllegalStateException When an active transaction * does not exist * @exception NullPointerException When the argument key is null */ void putResource(Object key, Object value); /** * The object is extracted from the resource map of the transaction * associated with the thread used when this method is invoked. * The key must be the same as the object specified in the * putResource method beforehand, in the same transaction. * If the specified key does not exist in the current resource * map, null is returned. * The general contract of this method is the same as the put * method of Map and the key must be other than null, but the * value can be set as null. * If the key is not stored in the map or if a null value is stored * for the key, the return value is null. * @param key Entry key of map * @return Value associated with the key * @exception IllegalStateException When an active transaction * does not exist * @exception NullPointerException When the argument key is null */ Object getResource(Object key); /** * Registers the synchronization instances invoked in a particular * order. * beforeCompletion of Synchronization registered with this * method is invoked after * SessionSynchronization.beforeCompletion, and * Synchronization.beforeCompletion, which is directly * registered in a transaction, are invoked, and before the 2-phase * commit processing starts. * Similarly, afterCompletion of Synchronization registered with * this method is invoked after the completion of 2-phase commit * processing and before SessionSynchronization.afterCompletion * and Synchronization.afterCompletion, which is directly * registered in the transaction, are invoked. * * beforeCompletion is invoked by the transaction context * associated with the thread when this method is invoked. * With beforeCompletion, access to resources such as connector * is permitted, but access is not permitted to user components * such as timer service and bean methods. * This is because the data managed on the invocation side and * the data that is already flushed by other Synchronization * registered with registerInterposedSynchronization might be * changed. * The general context becomes the context of the component * that invokes registerInterposedSynchronization. * * The context when afterCompletion is invoked is not defined. * Note that access to user components is not allowed. * Also, the resource can be closed, but * transactional operations cannot be performed for the resource. * * If this method is invoked when the transaction is not active, * IllegalStateException is thrown. * * If this method is invoked after the 2-phase commit processing * starts, IllegalStateException is thrown. * * @param sync Instance of Synchronization to be registered * @exception IllegalStateException When an active transaction * does not exist */ void registerInterposedSynchronization(Synchronization sync); /** * When this method is invoked, the status of the transaction * associated with the thread is returned. * The return value of this method is the same as the result of * TransactionManager.getStatus(). * * @return Status of the transaction associated with * the thread when this method is invoked. */ int getTransactionStatus(); /** * When this method is invoked, the transaction associated with * the thread is marked for rollback. * * @exception IllegalStateException When an active transaction * does not exist */ void setRollbackOnly(); /** * When this method is invoked, returns information about whether * the transaction associated with the thread is marked for * rollback. * * @return true if the transaction is marked for rollback * @exception IllegalStateException When an active transaction * does not exist */ boolean getRollbackOnly(); }