package com.fp.persistence.commondb; import java.lang.reflect.Field; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import javax.persistence.Column; import javax.persistence.EmbeddedId; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.FlushModeType; import javax.persistence.Persistence; import javax.persistence.Table; import javax.persistence.metamodel.EntityType; import org.hibernate.SQLQuery; import org.hibernate.Session; import com.fp.common.helper.BeanManager; import com.fp.common.logger.APPLogger; import com.fp.persistence.commondb.data.ThreadFacade; /** * Clase que se encarga del manejo de la favtoria de EntityManager. * * @author Jorge Vaca * @version 2.1 */ public class PersistenceManager { /** * Key para genrar un map de los beans mapeados en el archivo de hbconfiguration. */ public static final String NAME = "NAMES"; /** * Key que alamacena el numero de sessiones abiertas en el sessionfactory. */ public static final String OPEN = "OPEN"; /** * Key que alamacena el numero de sessiones cerradas en el sessionfactory. */ public static final String CLOSED = "CLOSED"; /** * Key que almacenal hora en la que se genero el sessionfactory . */ public static final String START_TIME = "START TIME"; /** * Instancia a la que hace referencia el Sigleton */ private static PersistenceManager instance = null; /** * Map de EntityManagerFactory ejb por compania. */ private final Map memfejb = new HashMap(); /** * Map de EntityManagerFactory local por compania. */ private final Map memf = new HashMap(); /** * Map de EntityManagerFactory auxiliar por persistence unit. */ private final Map memfaux = new HashMap(); /** * Metodo que entrega una instancia de PersistenceManager, si existe una creada la entrega, caso contrario crea una. * Adicionalmenet hace el mapping de las tablas del modelo relacional al modelo de objetos, creando el * EntityManagerFactory. * * @return PersistenceManager */ public static PersistenceManager getInstance() { synchronized (PersistenceManager.class) { if (PersistenceManager.instance == null) { PersistenceManager.instance = new PersistenceManager(); PersistenceManager.instance.fillEntityManagerFactory(); } else { Integer cia = PersistenceManager.getCompany(); if (((PersistenceManager.instance.memfejb.get(cia) == null) && PersistenceManager.iSEjb()) || (PersistenceManager.instance.memf.get(cia) == null)) { PersistenceManager.instance.fillEntityManagerFactory(); } } } return PersistenceManager.instance; } /** * Contruye el entitymanager falctory. */ private void fillEntityManagerFactory() { Integer cia = PersistenceManager.getCompany(); if ((PersistenceManager.instance.memfejb.get(cia) == null) && PersistenceManager.iSEjb()) { APPLogger.getLogger().error("CREANDO ENTYTY MANAGER FACTORY EJB: " + cia); try { PersistenceManager.instance.memfejb.put(cia, PersistenceManager.getEntityManagerFactory("ejb", cia)); APPLogger.getLogger().error("CREO ENTYTY MANAGER FACTORY EJB: " + cia); } catch (Exception e) { APPLogger.getLogger().error("NO PUEDE CONSTRUIR EL ENTYTY MANAGER FACTORY EJB" + cia); APPLogger.getLogger().error(e, e); } } if (PersistenceManager.instance.memf.get(cia) == null) { APPLogger.getLogger().error("CREANDO ENTYTY MANAGER FACTORY LOCAL: " + cia); try { PersistenceManager.instance.memf.put(cia, PersistenceManager.getEntityManagerFactory("local", cia)); APPLogger.getLogger().error("CREO ENTYTY MANAGER FACTORY LOCAL: " + cia); } catch (Exception e) { APPLogger.getLogger().error("NO PUEDE CONSTRUIR EL ENTYTY MANAGER FACTORY LOCAL" + cia); APPLogger.getLogger().error(e, e); } } } /** * Metodo que crea y entrega un EntityManagerFactory, dado el persistenceunit mas el codigo de compania. * * @param pUnit Nombre del persistenceunit con el cual se crea el EntityManagerFactory. * @param pCompany Codigo de compania. * @return EntityManagerFactory * @throws Exception */ private static EntityManagerFactory getEntityManagerFactory(String pUnit, Integer pCompany) throws Exception { Map configOverrides = new HashMap(); configOverrides.put("hibernate.ejb.cfgfile", "hibernateFlipMapping.cfg.xml"); EntityManagerFactory emf = null; emf = Persistence.createEntityManagerFactory(pUnit + pCompany, configOverrides); return emf; } /** * Metodo que entrega una instancia de PersistenceManager para pruebas, si existe una creada la entrega, caso * contrario crea una. Adicionalmenet hace el mapping de las tablas del modelo relacional al modelo de objetos, * creando el EntityManagerFactory. * * @return PersistenceManager */ public static PersistenceManager getInstanceTest() { synchronized (PersistenceManager.class) { if (PersistenceManager.instance == null) { PersistenceManager.instance = new PersistenceManager(); } } Integer cia = PersistenceManager.getCompany(); if (PersistenceManager.instance.memf.get(cia) == null) { try { PersistenceManager.instance.memf.put(cia, PersistenceManager.getEntityManagerFactory("local", cia)); } catch (Exception e) { APPLogger.getLogger().error("NO PUEDE CONSTRUIR EL ENTYTY MANAGER FACTORY LOCAL" + cia, e); } // Para que no construya uno en pruebas. PersistenceManager.instance.memfejb.put(cia, PersistenceManager.instance.memf.get(cia)); } return PersistenceManager.instance; } /** * Constructor que se encarga de crear una instancia de PersistenceManager * * @param test */ public PersistenceManager() { } /** * Metodo que se encarga de crear un objeto EntityManager. * * @return EntityManager */ public EntityManager createEntityManager() { EntityManager em = memfejb.get(PersistenceManager.getCompany()).createEntityManager(); return em; } /** * Metodo que se encarga de crear un objeto EntityManager. * * @return EntityManager */ public EntityManager createEntityManagerLocal() { EntityManager em = memf.get(PersistenceManager.getCompany()).createEntityManager(); em.setFlushMode(FlushModeType.COMMIT); return em; } /** Cierra el SessionFactory */ public void close() { memfejb.get(PersistenceManager.getCompany()).close(); } /** * Entrega EntityManagerFactory dado el persistenceunit name, se utiiza para conecciones auxiliares a bases de * datos, ejemplo cobis. * * @return Map */ public EntityManagerFactory getEntityManagerFactoryAuxiliar(String pUnit) { EntityManagerFactory emf = memfaux.get(pUnit); if (emf == null) { emf = Persistence.createEntityManagerFactory(pUnit); memfaux.put(pUnit, emf); } return emf; } /** * Permite Fijar el estado de Trace de la Conexión * * @param pSession Session de hibernate de Referencia * @param pStatus Estado del Trace. * @throws SQLException * @throws Exception */ public void setTrace(Session pSession, boolean pStatus) { SQLQuery sql = pSession.createSQLQuery("alter session set sql_trace =" + pStatus); sql.executeUpdate(); } /** * Entrega el codigo de compania de trabajo. * * @return Integer * @throws Exception */ private static Integer getCompany() { return ThreadFacade.getSessionData().getCompany(); } private static boolean iSEjb() { return ThreadFacade.getSessionData().isEjb(); } public Class findEntityClass(String pTable) throws Exception { return this.findEntity(pTable).getJavaType(); } public EntityType findEntity(String pTable) throws Exception { EntityManagerFactory emf = PersistenceHelper.getEntityManager().getEntityManagerFactory(); Set> set = emf.getMetamodel().getEntities(); EntityType entity = null; for (EntityType entityType : set) { Table t = entityType.getJavaType().getAnnotation(Table.class); if (t.name().compareTo(pTable) == 0) { entity = entityType; break; } } return entity; } @SuppressWarnings("rawtypes") public static List getDataBasePKFields(Class bean) { List ldata = new ArrayList(); for (Field f : bean.getDeclaredFields()) { if (f.isAnnotationPresent(EmbeddedId.class)) { Class pkT = f.getType(); for (Field f1 : pkT.getDeclaredFields()) { if (f1.isAnnotationPresent(Column.class)) { ldata.add("pk." + f1.getAnnotation(Column.class).name().toLowerCase()); } } } } if (ldata.isEmpty()) { ldata.add("pk"); } return ldata; } public List getDataBaseFields(String pTable) throws Exception { List data = new ArrayList(); Class et = this.findEntityClass(pTable); for (Field f : et.getDeclaredFields()) { if (f.isAnnotationPresent(Column.class)) { data.add(f.getAnnotation(Column.class).name()); } if (f.isAnnotationPresent(EmbeddedId.class)) { Class pkT = f.getType(); for (Field f1 : pkT.getDeclaredFields()) { if (f1.isAnnotationPresent(Column.class)) { data.add(f1.getAnnotation(Column.class).name()); } } } } return data; } /** * Entrega el tipo de dato de un campo de una clase. Si no encuentra el campo retorna null. * * @param clase Clase a buscar el tipo de dato de un campo. * @param field Nombre del campo a buscar en la clase. * @return Class */ public static Class getType(Class clase, String field) { Class tipo = null; for (Field f : clase.getDeclaredFields()) { tipo = f.getType(); if (f.isAnnotationPresent(EmbeddedId.class)) { for (Field f1 : tipo.getDeclaredFields()) { if (f1.isAnnotationPresent(Column.class) && f1.getName().equals(field)) { tipo = f1.getType(); return tipo; } } } if (f.isAnnotationPresent(Column.class) && f.getName().equals(field)) { return tipo; } } return null; } /** * Convierte el valor al tipo de satos del atributo de la clase. * * @param bean Nombre de la clase a buscar el tipo de datos de un campo. * @param field Nombre del campo a buscar el tipo de dato. * @param value Valor a transformar al tipo de dato de una clase. * @return Object * @throws Exception */ public static Object changeType(String bean, String field, Object value) throws Exception { if (value == null) { return value; } // Convierte el valor del criterio al tipo especifico del campo de la clase. Class tipo = PersistenceManager.getType(Class.forName(bean), field.replace("pk.", "")); if (tipo != null) { value = BeanManager.convertObject(value, tipo); } return value; } }