package com.fp.hbm.helper; import java.io.Serializable; import java.sql.Timestamp; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.Transaction; import com.fp.common.exception.CommonException; import com.fp.common.helper.BeanManager; import com.fp.common.logger.APPLogger; import com.fp.persistence.commondb.exception.CommondbException; import com.fp.persistence.commondb.helper.FormatDates; import com.fp.dto.hb.HibernateBean; import com.fp.dto.hb.History; /** * Helper que almacena Threads de session, transaccion, y FinancialSession utilizadas en el proceso de transacciones financieras. */ public class PersistenceHelperHQL { /** * Almacena una session de Hibernate. */ private static final ThreadLocal threadSession = new ThreadLocal(); /** * Almacena una transaccion de Hibernate. */ private static final ThreadLocal threadTransaction =new ThreadLocal(); /** * Retorna una session de hibernate. * @return s * @throws CommonException * @throws Exception */ public static Session getSession() throws CommondbException { Session s = threadSession.get(); if (s == null) { throw new CommondbException("COMMONDB-0004","SESION NO ASOCIADA A UNA TRANSACCION"); } return s; } public static void closeSession(){ try{ getSession().close(); }catch (Exception e) { APPLogger.getLogger().error(e); } } /** * Fija una session de hibernate. * @param session * @throws Exception */ public static void setSession(Session session) { threadSession.set(session); } /** * Inicia el proceso de una transaccion de hibernate.. * @throws CommonException * @throws HibernateException * @throws Exception */ public static void beginTransaction() throws HibernateException, CommondbException { Transaction tx = threadTransaction.get(); if (tx == null) { tx = getSession().beginTransaction(); threadTransaction.set(tx); } } /** * Graba los dml que estan en la transaccion. * @throws CommonException * @throws Exception */ public static void commitTransaction() throws CommondbException { Transaction tx = threadTransaction.get(); try { if ( tx != null && !tx.wasCommitted() && !tx.wasRolledBack() ){ tx.commit(); }else{ throw new CommondbException("COMMONDB-0005","TRANSACCION YA APLICADA"); } }finally{ threadTransaction.set(null); } } /** * Graba los dml que estan en la transaccion. * @throws CommondbException */ public static void flushTransaction() throws CommondbException { Session s = getSession(); s.flush(); } /** * rollback de los dml que estan dentro de la transaccion. * @throws CommonException */ public static void rollbackTransaction() throws CommondbException { Transaction tx = threadTransaction.get(); try { if ( tx != null && !tx.wasCommitted() && !tx.wasRolledBack() ){ tx.rollback(); }else{ throw new CommondbException("COMMONDB-0005","TRANSACCION YA APLICADA"); } }finally{ threadTransaction.set(null); } } /** * Retorna verdadero si a la transaccion se dio un commit; * @return boolean * @throws Exception */ public static boolean isCommitted() throws Exception { Transaction tx = threadTransaction.get(); if ( tx != null && !tx.wasCommitted() ){ return false; } return true; } /** * Retorna verdadero si a la transaccion se dio un commit; * @return boolean * @throws Exception */ public static boolean isRolledBack() throws Exception { Transaction tx = threadTransaction.get(); if ( tx != null && !tx.wasRolledBack() ){ return false; } return true; } /** * Metodo que se encarga de grabar un registro en la base de datos. * @param pBean Bean a grabar en la base de datos. * @throws CommondbException */ public static void save(HibernateBean pBean) throws CommondbException { Session s=PersistenceHelperHQL.getSession(); s.save(pBean.getClass().getName(),pBean); } /** * Inserta un registro en la base de datos. * @param pClassName Nombre de la clase que maneja la persistencia de una tabla. * @param pBean Bean a insertar. * @throws CommonException * @throws Exception */ public static void save(String pClassName,HibernateBean pBean) throws CommondbException { Session s=PersistenceHelperHQL.getSession(); s.save(pClassName,pBean); } /** * Actualiza un registro en la base de datos. * @param pBean Bean a actualiar. * @throws CommonException * @throws Exception */ public static void update(HibernateBean pBean) throws CommondbException { Session s=PersistenceHelperHQL.getSession(); s.update(pBean.getClass().getName(),pBean); } /** * Actualiza un registro en la base de datos. * @param pClassName Nombre de la clase que maneja la persistencia de una tabla. * @param pBean Bean a actualiar. * @throws CommonException * @throws Exception */ public static void update(String pClassName,HibernateBean pBean) throws CommondbException { Session s=PersistenceHelperHQL.getSession(); s.update(pClassName,pBean); } /** * Actualiza o inserta un registro en la base de datos. * @param pBean Bean a actualiar o insertar. * @throws CommonException * @throws Exception */ public static void saveOrUpdate(HibernateBean pBean) throws CommondbException,Exception { Session s=PersistenceHelperHQL.getSession(); HibernateBean bean = manageHistory(pBean); s.saveOrUpdate(pBean.getClass().getName(),bean); } public static void persist(HibernateBean pBean) throws CommondbException { Session s=PersistenceHelperHQL.getSession(); s.persist(pBean); } /** * Actualiza o inserta un registro en la base de datos. * @param pClassName Nombre de la clase que maneja la persistencia de una tabla. * @param pBean Bean a actualiar o insertar. * @throws CommonException * @throws Exception */ public static void saveOrUpdate(String pClassName,HibernateBean pBean) throws CommondbException,Exception { Session s=PersistenceHelperHQL.getSession(); HibernateBean bean = manageHistory(pBean); s.saveOrUpdate(pClassName,bean); } /** * Caduca registro persistente. * @param pBean Bean a caducar. * @throws CommonException * @throws Exception */ public static void delete(HibernateBean pBean) throws CommondbException { Session s=PersistenceHelperHQL.getSession(); s.delete(pBean.getClass().getName(),pBean); } @SuppressWarnings("unchecked") public static HibernateBean get(Class pClass,Serializable pKey) throws CommondbException{ Session s=PersistenceHelperHQL.getSession(); return (HibernateBean)s.get(pClass, pKey); } /** * Metodo que se encarga del manejo de la historia de registros en la base, si estos manejan date from date to. * @param pBean Bena a almacenar en la base de datos. * @return HibernateBean * @throws Exception */ private static HibernateBean manageHistory(HibernateBean pBean) throws Exception { Session s = PersistenceHelperHQL.getSession(); Object id = BeanManager.getBeanAttributeValue(pBean, "pk"); HibernateBean oldbean = null; HibernateBean newbean = pBean; if ((id instanceof History) ) { History pk = (History)id; if(pk.getDateto() != null){ s.evict(pBean); newbean = (HibernateBean)pBean.cloneMe(); oldbean = (HibernateBean) s.get(pBean.getClass(), (Serializable) id); s.evict(oldbean); id = BeanManager.getBeanAttributeValue(newbean, "pk"); pk = (History)id; if(pk.getDateto().compareTo(FormatDates.getDefaultExpiryTimestamp()) < 0){ return pBean; } } Timestamp t = FormatDates.getInstance().getDataBaseTimestamp(); if (oldbean != null && !BeanManager.compareObject(pBean, oldbean) ) { expireRecord(oldbean,t); } Object tbean = BeanManager.getBeanAttributeValue(newbean, "datefrom"); //si el valor anterior de fdesde es null le asigan un valor. if(tbean == null){ BeanManager.setBeanAttributeValue(newbean, "datefrom", t); } BeanManager.setBeanAttributeValue(pk, "dateto", FormatDates.getDefaultExpiryTimestamp()); setpartition(pk, pk.getDateto()); } return newbean; } /** * Metodo que expira un registro en la base de datos. * @param pOldBean Objeto que contiene el registro de una tabla a expirar. * @param pTimestamp Fecha con la cual se expira un registro. * @throws Exception */ private static void expireRecord(HibernateBean pOldBean,Timestamp pTimestamp) throws Exception { Session s = PersistenceHelperHQL.getSession(); History pk = (History)BeanManager.getBeanAttributeValue(pOldBean, "pk"); pk.setDateto(pTimestamp); setpartition(pk, pTimestamp); s.save(pOldBean.getClass().getName(),pOldBean); } /** * Metodo fija la particion en un registro, la particion es yyyymm del campo dateto. * @param pHistory Pk de un registro. * @param pTimestamp fecha con la cual se caduca un registro. * @throws Exception */ private static void setpartition(History pHistory,Timestamp pTimestamp) throws Exception { try { BeanManager.setBeanAttributeValue(pHistory, "partition", FormatDates.getPartition(pTimestamp)); } catch (Exception e1) { } } }