001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.ejb3.entity;
023:
024: import javax.persistence.EntityManager;
025: import javax.persistence.EntityManagerFactory;
026: import javax.persistence.PersistenceContextType;
027: import javax.persistence.TransactionRequiredException;
028: import javax.transaction.RollbackException;
029: import javax.transaction.Synchronization;
030: import javax.transaction.SystemException;
031: import javax.transaction.Transaction;
032: import org.jboss.logging.Logger;
033: import org.jboss.tm.TransactionLocal;
034: import org.jboss.tm.TxManager;
035: import org.jboss.tm.TxUtils;
036: import org.jboss.ejb3.ThreadLocalStack;
037: import org.jboss.ejb3.tx.TxUtil;
038:
039: import java.util.IdentityHashMap;
040: import java.util.Map;
041:
042: /**
043: * @author <a href="mailto:gavine@hibernate.org">Gavin King</a>
044: * @version $Revision: 57207 $
045: */
046: public class ManagedEntityManagerFactory {
047: private static final Logger log = Logger
048: .getLogger(ManagedEntityManagerFactory.class);
049:
050: protected EntityManagerFactory entityManagerFactory;
051: protected TransactionLocal session = new TransactionLocal(TxUtil
052: .getTransactionManager());
053: protected String kernelName;
054:
055: public static ThreadLocalStack<Map> nonTxStack = new ThreadLocalStack<Map>();
056:
057: public EntityManager getNonTxEntityManager() {
058: Map map = nonTxStack.get();
059: EntityManager em = (EntityManager) map.get(this );
060: if (em == null) {
061: em = entityManagerFactory.createEntityManager();
062: map.put(this , em);
063: }
064: return em;
065: }
066:
067: public ManagedEntityManagerFactory(EntityManagerFactory sf,
068: String kernelName) {
069: this .entityManagerFactory = sf;
070: this .kernelName = kernelName;
071: }
072:
073: public EntityManagerFactory getEntityManagerFactory() {
074: return entityManagerFactory;
075: }
076:
077: public String getKernelName() {
078: return kernelName;
079: }
080:
081: public void destroy() {
082: entityManagerFactory.close();
083: }
084:
085: private static class SessionSynchronization implements
086: Synchronization {
087: private EntityManager manager;
088: private Transaction tx;
089: private boolean closeAtTxCompletion;
090:
091: public SessionSynchronization(EntityManager session,
092: Transaction tx, boolean close) {
093: this .manager = session;
094: this .tx = tx;
095: closeAtTxCompletion = close;
096: }
097:
098: public void beforeCompletion() {
099: /* IF THIS GETS REACTIVATED THEN YOU MUST remove the if(closeAtTxCompletion) block in getSession()
100: try
101: {
102: int status = tx.getStatus();
103: if (status != Status.STATUS_ROLLEDBACK && status != Status.STATUS_ROLLING_BACK && status != Status.STATUS_MARKED_ROLLBACK)
104: {
105: if (FlushModeInterceptor.getTxFlushMode() != FlushModeType.NEVER)
106: {
107: log.debug("************** flushing.....");
108: manager.flush();
109: }
110: }
111: }
112: catch (SystemException e)
113: {
114: throw new RuntimeException(e);
115: }
116: */
117: }
118:
119: public void afterCompletion(int status) {
120: if (closeAtTxCompletion) {
121: log
122: .debug("************** closing entity managersession **************");
123: manager.close();
124: }
125: }
126: }
127:
128: public static ThreadLocal longLivedSession = new ThreadLocal();
129:
130: public TransactionLocal getTransactionSession() {
131: return session;
132: }
133:
134: public void registerExtendedWithTransaction(EntityManager pc) {
135: pc.joinTransaction();
136: session.set(pc);
137: }
138:
139: public void verifyInTx() {
140: Transaction tx = session.getTransaction();
141: if (tx == null || !TxUtils.isActive(tx))
142: throw new TransactionRequiredException(
143: "EntityManager must be access within a transaction");
144: if (!TxUtils.isActive(tx))
145: throw new TransactionRequiredException(
146: "Transaction must be active to access EntityManager");
147: }
148:
149: public boolean isInTx() {
150: Transaction tx = session.getTransaction();
151: if (tx == null || !TxUtils.isActive(tx))
152: return false;
153: return true;
154: }
155:
156: public EntityManager getTransactionScopedEntityManager() {
157: Transaction tx = session.getTransaction();
158: if (tx == null || !TxUtils.isActive(tx))
159: return getNonTxEntityManager();
160:
161: EntityManager rtnSession = (EntityManager) session.get();
162: if (rtnSession == null) {
163: rtnSession = createEntityManager();
164: try {
165: tx.registerSynchronization(new SessionSynchronization(
166: rtnSession, tx, true));
167: } catch (RollbackException e) {
168: throw new RuntimeException(e); //To change body of catch statement use Options | File Templates.
169: } catch (SystemException e) {
170: throw new RuntimeException(e); //To change body of catch statement use Options | File Templates.
171: }
172: session.set(rtnSession);
173: rtnSession.joinTransaction(); // force registration with TX
174: }
175: return rtnSession;
176: }
177:
178: public EntityManager createEntityManager() {
179: return entityManagerFactory.createEntityManager();
180: }
181:
182: }
|