Boa noite,
Tenho uma aplicação que utilizando o Hibernate. Tenho meu HibernateUtil.
public class HibernateUtil {
private static final SessionFactory sessionFactory;
static {
try {
sessionFactory = new AnnotationConfiguration().configure()
.buildSessionFactory();
} catch (Throwable ex) {
System.err.println("Não foi possivel criar a SessionFactory." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static Session getSession() {
return sessionFactory.openSession();
}
}
Aí em cadas DAO eu utilizo o getSession
public void save(T instance){
Session sessao = HibernateUtil.getSession();
try {
sessao.beginTransaction();
sessao.merge(instance);
sessao.beginTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
}
}
Estou todo enrolado para aprender a gerenciar essa sessão. Sempre que tento um session.close (O que acho que deveria ser feito) ele dá erro que a sessão já foi fechada e não pode mais ser utiliza. Creio que isso ocorre pelo motivo que getSession ser static.
Mas minha pergunta é qual a melhor maneira de se gerenciar as sessoes que utilizo para realizar operações no banco de dados?
Vou te dar uma dica no metodo save, que poderá ser usado também nos demais saveOrUpdate ou delete ou update.
public void save(Object object) {
Session session = null;
try {
//abre a sessao
session = sessionFactory.openSession();
//inicia a transacao
session.beginTransaction();
//salva na sessao o objeto
session.save(object);
//executa o commit
session.getTransaction().commit();
} catch (HibernateException hex) {
if (session != null && session.getTransaction().isActive()) {
session.getTransaction().rollback();
}
throw hex;
} finally {
if (session != null && session.isOpen()) {
session.close();
}
}
}
Blz, já estou utilizando seu padrão ai. Obrigado!
Agora eu queria saber mais da teoria disso tudo. Só pelo que você fez no metodo save dá para garantir a transação disso tudo.
Bom gente estou tentando modificar meu sistema para gerenciar as sessões do Hibernate. Começando por tentar fechar as sessões utilizadas para operações com o banco de dados.
Aí entrei nos assuntos: session.load, session.get e detached.
Ao fazer uma consulta no banco de dados e recuperar com session.load um usuario tentei fechar a sessao e recebi um: Lazy Initialization Exception.
Descobri o porque sendo que meu usuário tem relacionamento com outros objetos tipo perfil, situacao, etc e o load trabalha com um Prozy e como a sessão foi fechado lançou a excessão.
Blz, entendi. (Se for isso mesmo)
Agora eu pergunto como fechar minha sessão nesse caso? Tentei o session.get mas a mesma excessão é lançada.
Agradeço aos que puderem ajudar.
Abraço!
vc vai ter que ter um filtro para gerenciar isso
em seus metodo vc pega a session mas nunca precisa mais fechar é só usar esse filtro
public class HibernateSessionRequestFilter implements Filter {
public void init(FilterConfig config) throws ServletException{}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HibernateUtil.beginTransaction();
try {
chain.doFilter(request, response);
HibernateUtil.commitTransaction();
} catch (HibernateException exception) {
exception.printStackTrace();
HibernateUtil.rollbackTransaction();
} finally {
HibernateUtil.closeSession();
}
}
public void destroy(){}
}
mapear ele no xml
<filter>
<filter-name>HibernateFilter</filter-name>
<filter-class>br.com.filter.HibernateSessionRequestFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HibernateFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Blz! Mas como utilizo isso nas minhas DAOs? Como ficaria um exemplo da utilização do filtro nas DAOs?
Obrigado.
Se puder indicar uns links sobre a teoria disso tudo? Isso é um padrão?
Vlw!
tambem estou com a mesma duvida mais nesse caso de colocar um filtro quando eu abrir a session dentro do dao não vai ser o mesmo objeto então não fecharia uma session diferente da que eu uso no DAO?
Obrigado!
não! vc teria que ter um HibernateUtil trabalando com sessionfactory e os daos extends a ele ou um dao generico e os demais daos extends ao dao generico quando à fechar a session diferente isso é tem que ser tratado na propria classe de pegar a session.
No site do hibernate tem o exemplo deste filtro de forma até mais complicada e mais tratada e tabém trabalhar com um HibernateUtil e Dao generico
Arthur eu trabalho com o HibernateUtil:
public class HibernateUtil {
private static final SessionFactory sessionFactory;
static {
try {
sessionFactory = new AnnotationConfiguration().configure()
.buildSessionFactory();
} catch (Throwable ex) {
System.err.println("Não foi possivel criar a SessionFactory." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static Session getSession() {
return sessionFactory.openSession();
}
}
Os dados de conexão, como você sabe, estão no hibernate.cfg.xml.
Aí eu tenho a DAOGenerica. Um exemplo do método save:
public abstract class GenericDAO<T> implements GenericRepository<T>{
Class<T> persistentClass;
@SuppressWarnings("unchecked")
public GenericDAO(Class clazz) {
this.persistentClass = clazz;
}
public void save(T instance){
Session sessao = HibernateUtil.getSession();
Transaction transacao = sessao.beginTransaction();
try {
transacao.begin();
sessao.saveOrUpdate(instance);
sessao.flush();
transacao.commit();
} catch (HibernateException hex) {
if(sessao != null && transacao.isActive()) {
transacao.rollback();
}
throw hex;
}finally {
if(sessao != null && sessao.isOpen()) {
sessao.close();
}
}
}
Com isso aí minha sessão está bem gerenciada?
Estava pensando em gerencia a Session em um filtro abrindo e fechando as transactions a cada request.
não daria certo?
Obrigado!
leiam um pouco sobre o padrão “Open Session in View” - OSV
seu hibernate util ta faltando coisas como guardar as session em ThreadLocal
http://www.guj.com.br/posts/list/37285.java
http://community.jboss.org/wiki/OpenSessioninView // <-------------lei tudo se puder
Estou com esse mesmo problema utilizando Hibernate com RIAs feitas com Flex.
Nas meus DAOs tento fazer dessa forma, mas ao fechar um sessão, não consigo abrir em outra chamada.
public void save(T instance){
Session sessao = HibernateUtil.getSession();
Transaction transacao = sessao.beginTransaction();
try {
transacao.begin();
sessao.saveOrUpdate(instance);
sessao.flush();
transacao.commit();
} catch (HibernateException hex) {
if(sessao != null && transacao.isActive()) {
transacao.rollback();
}
throw hex;
}finally {
if(sessao != null && sessao.isOpen()) {
sessao.close();
}
}
}
Então, eu fiz o seguinte:
public class SolicitanteDAO {
private static Session sessao;
public static boolean incluir(Solicitante solicitante) {
if (sessao == null) {
sessao = HibernateUtil.getSessionFactory().openSession();
}
if (sessao != null) {
try {
//criptografa a senha
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
BigInteger senhaCriptografada = new BigInteger(1, md5.digest(solicitante.getSenha().getBytes()));
solicitante.setSenha(senhaCriptografada.toString(16));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
//atribuir data
sessao.beginTransaction();
sessao.save(solicitante);
sessao.getTransaction().commit();
sessao.flush();
sessao.clear();
return true;
} catch (Exception e) {
sessao.getTransaction().rollback();
return false;
}
}
return false;
}
Pelo que eu entendi, uma vez aberta uma sessão, ela será utilizada (naquele DAO) até o final do uso do sistema. O desempenho ficou muito bom, mas existe algum problema em fazer isso?
cara eu criei um dao generico usando generics
depois criei um DaoFactory que faz o controle de sessao que usa o hibernate util
package br.com.caelum.lojavirtual.util;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
public class HibernateUtil {
private static SessionFactory factory;
static{
Configuration conf = new AnnotationConfiguration();
conf.configure();
factory = conf.buildSessionFactory();
}
public static Session getSession(){
return factory.openSession();
}
}
ai fiz um dao generico
package br.com.caelum.lojavirtual.dao;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
public class Dao<T>{
private final Session session;
private final Class classe;
public Dao(Session session , Class classe){
this.session = session;
this.classe = classe;
}
public void adiciona(T entity){
this.session.save(entity);
}
public void remove(T entity){
this.session.delete(entity);
}
public void altera(T entity){
this.session.merge(entity);
}
public List<T> listaTudo(){
return this.session.createCriteria(this.classe).list();
}
public T procurar(Long id){
return (T) this.session.load(this.classe, id);
}
public List<T> FiltrarPorComlumn(String column , Object value){
return (List<T>) this.session.createCriteria(this.classe).add(Restrictions.eq(column , value)).list();
}
protected Session getSession(){
return this.session;
}
}
e um dao factory
package br.com.caelum.lojavirtual.dao;
import org.hibernate.Session;
import org.hibernate.Transaction;
import br.com.caelum.lojavirtual.modelo.Cd;
import br.com.caelum.lojavirtual.modelo.Musica;
import br.com.caelum.lojavirtual.modelo.TipoVenda;
import br.com.caelum.lojavirtual.modelo.Venda;
import br.com.caelum.lojavirtual.util.HibernateUtil;
public class DaoFactory {
private final Session session;
private Transaction transaction;
public DaoFactory(){
session = HibernateUtil.getSession();
}
public void beginTransaction(){
this.transaction = this.session.beginTransaction();
}
public void commit(){
this.transaction.commit();
this.transaction = null;
}
public boolean hasTransaction(){
return this.transaction != null;
}
public void rollback(){
this.transaction.rollback();
this.transaction = null;
}
public void close(){
this.session.close();
}
public UsuarioDao getUsuarioDao(){
return new UsuarioDao(this.session);
}
public Dao<Cd> getCdDao(){
return new Dao(this.session , Cd.class);
}
public Dao<Musica> getMusicaDao(){
return new Dao(this.session , Musica.class);
}
public Dao<Venda> getVendaDao(){
return new Dao(this.session , Venda.class);
}
public Dao<TipoVenda> getTipoVendaDao(){
return new Dao(this.session , TipoVenda.class);
}
}
qualquer coisa pode mandar email
hiroshisilva@gmail.com