Arquivo da tag: multiplos

Como usar vários bancos de dados com JPA/Hibernate

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?