Duvida de Como se Trabalhar Com Hibernate

10 respostas
colored

Bom durante um tempo eu venho utilizando as minhas classes desta forma, mas dps de ver a apostila da caelum,
eu fikei meio na duvida se eh uma das formas corretas de se trabalhar ou não…

HibernateUtil

public class HibernateUtil {
	
	private static Logger log = Logger.getLogger(HibernateUtil.class);
	private static SessionFactory factory;
	
	static{
		AnnotationConfiguration cfg = new AnnotationConfiguration();
		cfg.configure();
		factory = cfg.buildSessionFactory();
	}
	
	public static Session getSession(){
		log.info("Opening New Session");
			Session session = factory.openSession();
			session.beginTransaction();
		return session;
	}

}
public class GenericDao {
	
	protected Session getSession(){
		return HibernateUtil.getSession();
	}
	
	protected void genericSaveOrUpdate(Serializable pojo){
		Session s = getSession();
		s.saveOrUpdate(pojo);
		s.beginTransaction().commit();
		s.close();
	}

	protected Serializable genericGet(Class classToSearch, Serializable key){
		Session s = getSession();
		Serializable retorno = (Serializable) s.get(classToSearch, key);
		s.close();
		return retorno;
	}
	
	protected void genericRemove(Serializable pojo){
		Session s = getSession();
		s.delete(pojo);
		s.beginTransaction().commit();
		s.close();
	}
	
	protected <T extends Serializable> List<T> ListAllClass(Class<T> classe){
		Criteria c = getSession().createCriteria(classe);
		return c.list();
	}
}

Tipo keria saber c eh um jeito certo, pq vi algumas coisas e n tem mto haver com meu codigo…

Obrigado :}

10 Respostas

Cherubini

Bom eu tbm fazia como vc!!!

mais depois q o projetos da empresa migrarao para EJB3 ou Spring 2.5
nunca mais usei o HibernateUtil ou o JPAUtil ! xP

pois o container ja prove isso para vc!!

bom, oq vc pode fazer ai é colocar seu session e sua transaction em uma Thread local

assim:

/* Threads que controlarão a sessão e a transação */
    private static final ThreadLocal<Session> threadSession = new ThreadLocal<Session>();
    private static final ThreadLocal<Transaction> threadTransaction = new ThreadLocal<Transaction>();

    /* Variaveis do Hibernate */
    private static final Configuration cfg = new AnnotationConfiguration();
    private static SessionFactory sessionFactory;

ai vc cria os metodos para dar session, transaction,commit,flush, rollback,close session!!

e nas suas clases vc so chama os metodos staticos , sem ter q abrir sempre a msm transacao e tals!!!

espero ter ajudado !!

flws

colored

Tipo eu n manjo nd de thread…

Mas o sistema varias pessoas vao ter q acessar…
PRa q akelas threads criadas?

Cherubini

tipo olha a classe inteira:

public class HibernateSessionFactory {
	/**
     * Construtor no-arg
     * Protegido para evitar a criação da classe
     */
    protected HibernateSessionFactory() {
        super();
    }

    /* Constante de caminho do arquivo de configuração do Hibernate */

    /* Threads que controlarão a sessão e a transação */
    private static final ThreadLocal<Session> threadSession = new ThreadLocal<Session>();
    private static final ThreadLocal<Transaction> threadTransaction = new ThreadLocal<Transaction>();

    /* Variaveis do Hibernate */
    private static final Configuration cfg = new AnnotationConfiguration();
    private static SessionFactory sessionFactory;

    /**
     * Método que retorna a instancia da Sessão.
     * @return Session
     * @throws SessionFactoryException
     */
    public static Session getCurrentSession() throws HibernateException {
        Session session = threadSession.get();

        try {
            if (session == null || !session.isOpen()) {
                if (sessionFactory == null) {
                    try {
                        cfg.configure();
                        sessionFactory = cfg.buildSessionFactory();
                    }catch (Exception e) {
                        throw e;
                    }
                }
                session = (sessionFactory != null) ? sessionFactory.openSession() : null;

                threadSession.set(session);
            }
        } catch (Exception e) {
            throw new HibernateException(e);
        }

        return session;
    }

    /**
     * Método que fecha a sessão do Hibernate.
     * @throws SessionFactoryException
     */
    public static void doCloseSession() throws HibernateException {
        Session session = threadSession.get();
        threadSession.set(null);

        try {
            if (session != null) {
                session.close();
            }
        } catch (Exception e) {
            throw new HibernateException(e);
        }
    }

    /**
     * Método que inicia a transação do Hibernate.
     * @throws SessionFactoryException
     */
    public static void doBeginTransaction() throws HibernateException {
        Transaction tx = threadTransaction.get();

        try {
            if(tx == null){
                tx = getCurrentSession().beginTransaction();
                threadTransaction.set(tx);
            }
        } catch (Exception e) {
            throw new HibernateException(e);
        }
    }

    /**
     * Método que executa o rollback da transação.
     * @throws SessionFactoryException
     */
    public static void doRollback() throws HibernateException {
        Transaction tx = threadTransaction.get();

        try {
            if(tx != null && !tx.wasCommitted() && !tx.wasRolledBack()){
                tx.rollback();
                threadTransaction.set(null);
            }
        } catch (Exception e) {
            throw new HibernateException(e);
        }
    }
    //LIMPANDO CACHE PRIMÁRIO DO HIBERNATE
    //UTILIZADO PARA OPERACOES EM BATCH
    public static void doFlush(){
        try {
        	getCurrentSession().flush();
        	getCurrentSession().clear();
        } catch (Exception e) {
            throw new HibernateException(e);
        }
    }
    /**
     * Método que commita a transação.
     * @throws SessionFactoryException
     */
    public static void doCommit() throws HibernateException {
        Transaction tx = threadTransaction.get();

        try {
            if(tx != null && !tx.wasCommitted() && !tx.wasRolledBack()){
                tx.commit();
                threadTransaction.set(null);
            }
        } catch (Exception e) {
            doRollback();
            throw new HibernateException(e);
        }
    }
}

olha utilizando ela:

public Integer salvar(T u) throws DAOException {
		Integer key = new Integer(-1);
		try{
			doBeginTransaction();

			key = (Integer)getCurrentSession().save(u);

			doCommit();
		} catch(Exception e) {
			doRollback();
			e.printStackTrace();
		}
		return key;
	}

elas q vai controlar tudo para vc!!!E deixar o acesso bem estruturado!!
Resumindo use ThreadLocal quando quiser reaproveitar a Thread corrente, e não criar uma nova, pois ela é um mecanismo mais leve que a criação manual de uma Thread.

colored

kkk…
acho q eh mto avançado pra mim isso ai.

n entendi nd

Cherubini

huiehuiehiue!!!

q isso cara, pega com calma!!!

com a ThreadLocal eu tenho acesso seguro
para minhas sessions e transacoes!!Ela
vai gerenciar isso para vc!!!ao inves
de vc ficar na transacao toda hora abrindo
e fechando ou commitando ou dando rollback
é so chamar os metodos criados no seu HibernateUtil
que ele vai gerenciar isso para vc!!!

espero q ter ajudado!!Faz uns testes ai
que para você ver!!!

abraços flw

leonardofreitas8

Boa noite ...

Veja só a minha questão....

Tenho consultas variadas " por diversos parametros " que sempre me retornam um list, porem gostaria que no final do list tivesse um "Footer" com a somatória dos valores retornados da consulta, sendo assim criei uma variável chamada "somaEntrada" tipo BigDecimal e em seu GET coloquei meu método de soma (SUM) que atribui o valor da soma à variável...

Daí quando chamo no JSF value="#{meuBean.somaEntrada}" não retorna nenhuma soma quando os valores são listados... veja

private BigDecimal somaEntrada;


public BigDecimal getSomaEntrada() {
		
		Session session = HibernateUtil.getSession();
		Criteria criteria = (Criteria) session.createCriteria(Principal.class)
		//a coluna que quero somar chama-se "entrada"...
		.setProjection(Projections.sum("entrada")).uniqueResult();
		
		return somaEntrada;

conto com a ajuda de vcs...

colored

Então Cherubini ;D…

Eu olhei e vi q a unica coisa que vc faz…
Foi que no começo vc passa uma session pela thread…

passa as configurações nela e dps devolve pra thread…

e so com isso ja resolve todos problemas que vc estava comentando???

Cherubini

isso ai meu camarada ! xD

colored

Blz entao qdo eu chegar nessa parte eu testo esse seu modelo…

c n der te mando Pm :smiley:

Valeo

pauloperes

Cherubini,

Aproveitando o post, veja se o que eu faço esta incorreto:

Classe HibernateCore:

public class HibernateCore {

    private static SessionFactory sessionFactory;
    private static final ThreadLocal threadSession = new ThreadLocal();
    private static final ThreadLocal threadTransaction = new ThreadLocal();


    static {
        try {
            AnnotationConfiguration cfg = new AnnotationConfiguration();
            cfg.configure();
            sessionFactory = cfg.buildSessionFactory();
        } catch (Exception e) {
            e.printStackTrace(System.out);
        }
    }

    public static Session getSession() {
        Session s = (Session) threadSession.get();
        try {
            if (s == null) {
                s = sessionFactory.openSession();
                threadSession.set(s);
            }
        } catch (HibernateException ex) {
            ex.printStackTrace();
        }

        return s;
    }

    public static void closeSession() {
        try {
            Session s = (Session) threadSession.get();
            threadSession.set(null);
            if (s != null && s.isOpen()) {
                s.close();
            }
        } catch (HibernateException ex) {
            ex.printStackTrace();
        }
    }

    public static void beginTransaction() {
        Transaction tx = (Transaction) threadTransaction.get();
        try {
            if (tx == null) {
                tx = getSession().beginTransaction();
                threadTransaction.set(tx);
            }
        } catch (HibernateException ex) {
            ex.printStackTrace();
        }
    }

    public static void commitTransaction() {
        Transaction tx = (Transaction) threadTransaction.get();
        try {
            if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack()) {
                tx.commit();
            }
            threadTransaction.set(null);
        } catch (HibernateException ex) {
            ex.printStackTrace();
        }
    }

    public static void rollbackTransaction() {
        Transaction tx = (Transaction) threadTransaction.get();
        try {
            threadTransaction.set(null);
            if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack()) {
                tx.rollback();
            }
        } catch (HibernateException ex) {
            ex.printStackTrace();
        } finally {
            closeSession();
        }
    }

    public void doFlush(){
        try {
            getSession().flush();
            getSession().clear();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public AnnotationConfiguration getAnnotationConfiguration() {
        return new AnnotationConfiguration().configure();
    }
}

Classe Dao

public class Dao<T> {

    private Session session;
    private Class persistenceClass;

    public Class getPersistenceClass() {
        return persistenceClass;
    }

    public Session getSession() {
        return session;
    }

    public Dao(Session session, Class persistenceClass) {
        this.session = session;
        this.persistenceClass = persistenceClass;
    }

    public T load(int i) {
        return (T) this.session.load(persistenceClass, i);
    }

    public void save(T t) throws DaoException {
        try {
            this.session.save(t);
        } catch (HibernateException ex) {
            throw new DaoException(ex.getMessage());
        }
    }

    public void saveOrUpdate(T t) throws DaoException {
        try {
            this.session.saveOrUpdate(t);
        } catch (HibernateException ex) {
            throw new DaoException(ex.getMessage());
        }
    }

    public void delete(T t) {
        this.session.delete(t);
    }

    public void update(T t) {
        this.session.update(t);
    }

    public List<T> listAll() {
        return this.session.createCriteria(this.persistenceClass).list();
    }

    public T loadByExample(T t) {
        Criteria criteria = this.session.createCriteria(persistenceClass);
        criteria.add(Example.create(t).enableLike(MatchMode.START).excludeZeroes());
        return (T) criteria.uniqueResult();
    }
}

Veja que para cada dao que eu abro coloco uma session, o begintransaction e o comit transaction e faco depois, antes e depois do método save por exempo do dao, está correto, veja abaixo:

or (Shelf s : shelves) {            
            if (daoCity.getCityBySymbol(s.getCity().getSymbol()) == null) {
                try {
                    daoCity.getDaoGeneric().saveOrUpdate(s.getCity());
                } catch (DaoException ex) {
                    LogPersistence.logger.severe("Erro ao inserir a cidade: " + s.getCity().getName() + "\n" + ex.getMessage());
                }
            }
            
            HibernateCore.beginTransaction();
            // Verifica se o elemento ja esta cadastrado no sistema, caso nao esteja cadastra no sistema
            if (daoShelf.getShelfByIp(s.getIp()) == null) {                
                try {
                    daoShelf.getDaoGeneric().save(s);
                } catch (DaoException ex) {
                    LogPersistence.logger.severe("Erro ao inserir o elemento com ip: " + s.getIp() + "(" + s.getName() + ") \n" + ex.getMessage());
                }
                newShelves.add(s);
            }

            HibernateCore.commitTransaction();
        }
        return newShelves;

Ou seja em cada classe que eu uso um dao eu faco isto, pegando a transacao do HibernateCore.

Criado 20 de agosto de 2009
Ultima resposta 2 de nov. de 2009
Respostas 10
Participantes 4