/*
* ============================================================================
* GNU Lesser General Public License
* ============================================================================
*
* Beanlet - JSE Application Container.
* Copyright (C) 2006 Leon van Zantvoort
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*
* Leon van Zantvoort
* 243 Acalanes Drive #11
* Sunnyvale, CA 94086
* USA
*
* zantvoort@users.sourceforge.net
* http://beanlet.org
*/
package org.beanlet.persistence.impl;
import javax.persistence.*;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.metamodel.Metamodel;
import java.util.Map;
/**
* <ul>
* <li>When container-managed entity managers are used
* (in Java EE environments), the application does not interact with the
* entity manager factory. The entity managers are obtained directly through
* dependency injection or from JNDI, and the container manages interaction with
* the entity manager factory transparently to the application. (5.2 p114)
* <li>The container manages the persistence context lifecycle and the creation
* and the closing of the entity manager instance transparently to the
* application. (5.2.1 p114)
* <li>A container-managed entity manager must be a JTA entity manager. JTA
* entity managers are only specified for use in Java EE containers. (5.5 p118)
* <li>When a container-managed entity manager is used, the lifecycle of the
* persistence context is always managed automatically, transparently to the
* application, and the persistence context is propagated with the JTA
* transaction. (5.6 p120)
* <li>A container-managed persistence context may be defined to have either a
* lifetime that is scoped to a single transaction or an extended lifetime that
* spans multiple transactions, depending on the PersistenceContextType that is
* specified when its EntityManager is created. This specification refers to
* such persistence contexts as transaction-scoped persistence contexts and
* extended persistence contexts respectively. (5.6 p120)
* <li>Persistence contexts are always associated with an entity manager
* factory. (5.6 p121)
* <li>As described in section 5.1, a single persistence context may correspond
* to one or more JTA entity manager instances (all associated with the same
* entity manager factory). The persistence context is propagated across the
* entity manager instances as the JTA transaction is propagated. (5.6.3 p121)
* <li>Persistence contexts are propagated by the container across component
* invocations as follows.
*
* If a component is called and there is no JTA transaction or the JTA
* transaction is not propagated, the persistence context is not propagated.
* <ul>
* <li>If an entity manager is then invoked from within the component:
* <ul>
* <li>Invocation of an entity manager defined with PersistenceContext-
* Type.TRANSACTION will result in use of a new persistence context (as
* described in section 5.6.1).
* <li>Invocation of an entity manager defined with PersistenceContext-
* Type.EXTENDED will result in the use of the existing extended persistence
* context bound to that component.
* <li>If the entity manager is invoked within a JTA transaction, the
* persistence context will be bound to the JTA transaction.
* </ul>
* <li>If a component is called and the JTA transaction is propagated into
* that component:
* <ul>
* <li>If the component is a stateful session bean to which an extended
* persistence context has been bound and there is a different persistence
* context bound to the JTA transaction, an EJBException is thrown by the
* container.
* <li>Otherwise, if there is a persistence context bound to the JTA
* transaction, that persistence context is propagated and used.
* </ul>
* </ul>
* (5.6.3.1 p122)
* <li>Entity manager instances obtained from different entity manager factories
* never share the same persistence context. (p122)
* <li>For the management of a transaction-scoped persistence context, if there
* is no EntityManager already associated with the JTA transaction:
* <ul>
* <li>The container creates a new entity manager by calling
* EntityManagerFactory.createEntityManager when the first invocation of an
* entity manager with Persistence-ContextType.TRANSACTION occurs within the
* scope of a business method executing in the JTA transaction.
* <li>After the JTA transaction has completed (either by transaction commit
* or rollback), The container closes the entity manager by calling
* EntityManager.close.
* </ul>
* The container must throw the TransactionRequiredException if a
* transaction-scoped persistence context is used, and the EntityManager
* persist, remove, merge, or refresh method is invoked when no transaction
* is active.<br>
* <br>
* For stateful session beans with extended persistence contexts:
* <ul>
* <li>The container creates an entity manager by calling
* EntityManagerFactory.createEntityManager when a stateful session bean is
* created that declares a dependency on an entity manager with
* PersistenceContextType.EXTENDED. (See section 5.6.2).
* <li>The container closes the entity manager by calling EntityManager.close
* after the stateful session bean and all other stateful session beans that
* have inherited the same persistence context as the EntityManager have been
* removed.
* <li>When a business method of the stateful session bean is invoked, if the
* stateful session bean uses container managed transaction demarcation, and
* the entity manager is not already associated with the current JTA
* transaction, the container associates the entity manager with the current
* JTA transaction and calls EntityManager.joinTransaction. If there is a
* different persistence context already associated with the JTA transaction,
* the container throws the EJBException.
* <li>When a business method of the stateful session bean is invoked, if the
* stateful session bean uses bean managed transaction demarcation and a
* UserTransaction is begun within the method, the container associates the
* persistence context with the JTA transaction and calls
* EntityManager.joinTransaction.
* </ul>
* (5.9.1 p129)
* <li>The container must throw the IllegalStateException if the application
* calls EntityManager. close on a container-managed entity manager.
* (5.9.1 p130)
* <li>When the container creates an entity manager, it may pass a map of
* properties to the persistence provider by using the
* EntityManagerFactory.createEntityManager(Map map) method. If properties have
* been specified in the PersistenceContext annotation or the
* persistence-context-ref deployment descriptor element, this method must be
* used and the map must include the specified properties. (5.9.1 p130)
* </ul>
* @author Leon van Zantvoort
*/
abstract class ContainerManagedEntityManager implements EntityManager {
abstract EntityManager getEntityManager();
abstract void preInvoke();
abstract void postInvoke(boolean commit);
public void clear() {
getEntityManager().clear();
}
public Query createNativeQuery(String string, String string0) {
return getEntityManager().createNativeQuery(string, string0);
}
public void flush() {
getEntityManager().flush();
}
public Object getDelegate() {
return getEntityManager().getDelegate();
}
public FlushModeType getFlushMode() {
return getEntityManager().getFlushMode();
}
public EntityTransaction getTransaction() {
return getEntityManager().getTransaction();
}
public boolean isOpen() {
return getEntityManager().isOpen();
}
public void joinTransaction() {
getEntityManager().joinTransaction();
}
public boolean contains(Object object) {
return getEntityManager().contains(object);
}
public Query createNamedQuery(String string) {
return getEntityManager().createNamedQuery(string);
}
public Query createNativeQuery(String string) {
return getEntityManager().createNativeQuery(string);
}
public Query createQuery(String string) {
return getEntityManager().createQuery(string);
}
public void lock(Object object, LockModeType lockModeType) {
getEntityManager().lock(object, lockModeType);
}
public Query createNativeQuery(String string, Class aClass) {
return getEntityManager().createNativeQuery(string, aClass);
}
public void setFlushMode(FlushModeType flushModeType) {
getEntityManager().setFlushMode(flushModeType);
}
public <T> T getReference(Class<T> entityClass, Object primaryKey) {
return getEntityManager().getReference(entityClass, primaryKey);
}
public <T> T find(Class<T> entityClass, Object primaryKey) {
return getEntityManager().find(entityClass, primaryKey);
}
public <T> T merge(T entity) {
return getEntityManager().merge(entity);
}
public void remove(Object object) {
getEntityManager().remove(object);
}
public void refresh(Object object) {
getEntityManager().refresh(object);
}
public void persist(Object object) {
getEntityManager().persist(object);
}
public void close() {
throw new IllegalStateException("Container managed entity manager " +
"does not allow this function.");
}
public <T> TypedQuery<T> createNamedQuery(String name, Class<T> resultClass) {
return getEntityManager().createNamedQuery(name, resultClass);
}
public <T> T find(Class<T> entityClass, Object primaryKey, Map<String, Object> properties) {
return getEntityManager().find(entityClass, primaryKey, properties);
}
public <T> T find(Class<T> entityClass, Object primaryKey, LockModeType lockMode) {
return getEntityManager().find(entityClass, primaryKey, lockMode);
}
public <T> T find(Class<T> entityClass, Object primaryKey, LockModeType lockMode, Map<String, Object> properties) {
return getEntityManager().find(entityClass, primaryKey, lockMode, properties);
}
public void lock(Object entity, LockModeType lockMode, Map<String, Object> properties) {
getEntityManager().lock(entity, lockMode, properties);
}
public void refresh(Object entity, Map<String, Object> properties) {
getEntityManager().refresh(entity, properties);
}
public void refresh(Object entity, LockModeType lockMode) {
getEntityManager().refresh(entity, lockMode);
}
public void refresh(Object entity, LockModeType lockMode, Map<String, Object> properties) {
getEntityManager().refresh(entity, lockMode, properties);
}
public void detach(Object entity) {
getEntityManager().detach(entity);
}
public LockModeType getLockMode(Object entity) {
return getEntityManager().getLockMode(entity);
}
public void setProperty(String propertyName, Object value) {
getEntityManager().setProperty(propertyName, value);
}
public Map<String, Object> getProperties() {
return getEntityManager().getProperties();
}
public <T> TypedQuery<T> createQuery(CriteriaQuery<T> criteriaQuery) {
return getEntityManager().createQuery(criteriaQuery);
}
public <T> TypedQuery<T> createQuery(String qlString, Class<T> resultClass) {
return getEntityManager().createQuery(qlString, resultClass);
}
public <T> T unwrap(Class<T> cls) {
return getEntityManager().unwrap(cls);
}
public EntityManagerFactory getEntityManagerFactory() {
return getEntityManager().getEntityManagerFactory();
}
public CriteriaBuilder getCriteriaBuilder() {
return getEntityManager().getCriteriaBuilder();
}
public Metamodel getMetamodel() {
return getEntityManager().getMetamodel();
}
}