Olá pessoal! Hoje estou postando duas classes do meu projeto Generic Spatial DAO. Elas exemplificam como lidar com vários persistence unit e mostra o uso da classe ThreadLocal. Explicações no próprio código.
import java.util.HashMap; import java.util.Map; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import org.apache.log4j.Logger; /** * * @author joaosavio * */ public class EntityManagerFactoryService { private static final Logger LOG = Logger.getLogger(EntityManagerFactoryService.class); private static Map<String, EntityManagerFactory> factories = new HashMap<String, EntityManagerFactory>(); /** * This method returns an entity manager factory for a target persistence unit * * @param persistenceUnitName * @return an entity manager factory for a target persistence unit */ public static EntityManagerFactory getEntityManagerFactory( String persistenceUnitName) { if (factories.containsKey(persistenceUnitName)) { return factories.get(persistenceUnitName); } EntityManagerFactory emf; try { emf = Persistence.createEntityManagerFactory(persistenceUnitName); } catch (Exception e) { // handle exception } factories.put(persistenceUnitName, emf); return emf; } /** * Close entity manager factories. Use this method when application life cycle ends */ public static void closeFactories() { LOG.info("Closing entity manager factories"); for (Map.Entry entry : factories.entrySet()) { entry.getValue().close(); } factories.clear(); } }
package org.genericspatialdao.services; import java.util.HashMap; import java.util.Map; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.EntityTransaction; import org.apache.log4j.Logger; import org.genericspatialdao.exceptions.DAOException; /** * * @author Joao Savio C. Longo - joaosavio@gmail.com * */ public class EntityManagerService { private static final String THERE_IS_NO_ENTITY_MANAGER_IN_SESSION = "There is no entity manager in session"; private static final String THERE_IS_NO_SESSION = "There is no session"; private static final Logger LOG = Logger .getLogger(EntityManagerService.class); // there is a session for each persistence unit private static Map<String, ThreadLocal<EntityManager>> sessions = new HashMap<String, ThreadLocal<EntityManager>>(); /** * Get or create an entity manager * * @return an entity manager for a target persistence unit */ public static synchronized EntityManager getEntityManager( String persistenceUnitName) { ThreadLocal<EntityManager> session = sessions.get(persistenceUnitName); if (session == null) { session = new ThreadLocal<EntityManager>(); sessions.put(persistenceUnitName, session); } EntityManager em = session.get(); if (em == null) { EntityManagerFactory emf = EntityManagerFactoryService .getEntityManagerFactory(persistenceUnitName); LOG.info("Creating entity manager"); em = emf.createEntityManager(); session.set(em); } return em; } /** * Get the entity manager for session of a target persistence unit * * @return the entity manager for session of a target persistence unit */ public static synchronized EntityManager getEntityManagerForSession( String persistenceUnit) { LOG.debug("Getting entity manager for session: " + persistenceUnit); ThreadLocal<EntityManager> session = sessions.get(persistenceUnit); checkSession(session); EntityManager entityManager = session.get(); checkEntityManager(entityManager); return entityManager; } /** * Closes entity manager and remove it from session of a target persistence * unit */ public static synchronized void close(String persistenceUnit) { ThreadLocal<EntityManager> session = sessions.get(persistenceUnit); checkSession(session); EntityManager entityManager = session.get(); if (entityManager != null) { if (entityManager.isOpen()) { LOG.info("Closing entity manager"); entityManager.close(); } LOG.debug("Removing entity manager from session"); session.set(null); } } public static void closeAll() { LOG.info("Closing all entity managers"); for (String persistenceUnit : sessions.keySet()) { close(persistenceUnit); } } /** * Closes quietly entity manager and session of a target persistence unit */ public static synchronized void closeQuietly(String persistenceUnit) { try { close(persistenceUnit); } catch (DAOException e) { LOG.warn("Exception caught in closeQuietly method: " + e.getMessage()); } } /** * Begin a transaction if it is not active */ public static void beginTransaction(String persistenceUnit) { EntityManager em = getEntityManagerForSession(persistenceUnit); EntityTransaction transaction = em.getTransaction(); if (!transaction.isActive()) { LOG.debug("Beginning transaction"); transaction.begin(); } } /** * Commit if transaction is active */ public static void commit(String persistenceUnit) { EntityManager em = getEntityManagerForSession(persistenceUnit); EntityTransaction transaction = em.getTransaction(); if (transaction.isActive()) { LOG.info("Commiting"); transaction.commit(); } else { LOG.warn("Commit invoked but transaction is not active"); } } /** * Rollback if transaction is active */ public static void rollback(String persistenceUnit) { EntityManager em = getEntityManagerForSession(persistenceUnit); EntityTransaction transaction = em.getTransaction(); if (transaction.isActive()) { LOG.info("Rollbacking"); transaction.rollback(); } else { LOG.warn("Rollback invoked but transaction is not active"); } } private static void checkEntityManager(EntityManager entityManager) { if (entityManager == null) { LOG.error(THERE_IS_NO_ENTITY_MANAGER_IN_SESSION); throw new DAOException(THERE_IS_NO_ENTITY_MANAGER_IN_SESSION); } } private static void checkSession(ThreadLocal<EntityManager> session) { if (session == null) { LOG.error(THERE_IS_NO_SESSION); throw new DAOException(THERE_IS_NO_SESSION); } } }
Usamos o código acima da seguinte maneira:
EntityManager em = EntityManagerService.getEntityManager(persistenceUnitName);
Simples não?