Dúvida na delegação de controle entre as camadas MVC

1 resposta
davidbuzatto

Pessoal, é o seguinte, precisamos de opiniões sobre a seguinte situação.

Estamos desenvolvendo um pequeno sistema e usando na camada de persistência o hibernate. A nossa dúvida é referente a delegar controle sobre a transação e a sessão no hibernate.

Existem duas situações, e precisamos saber qual usar.

A primeira hipótese (implementada como teste nas listagens abaixo) é que deve-se criar a sessão e a transação fora dos DAOs, passar a sessao para os DAOs e no final na utilização dos mesmos dar um commit na transação e fechar a sessão.

A outra hipótese é deixar que o controle da sessão e da transação fique totalmente por responsabilidade do DAO.

Eu defendo a primeira hipótese, pois assim podemos ter maior controle.
O que vocês acham?
Dêem uma olhada nas listagens.

package usandohibernate.entity;

import javax.persistence.*;

/**
 *
 * @author David Buzatto
 */
@Entity
public class Cliente {
    
    @Id
    @GeneratedValue
    private Long id;
    
    @Column( 
        length = 30,
        nullable = false
    )
    private String nome;
    
    @Column( 
        length = 50,
        nullable = false
    )
    private String sobrenome;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getSobrenome() {
        return sobrenome;
    }

    public void setSobrenome(String sobrenome) {
        this.sobrenome = sobrenome;
    }
    
}
package usandohibernate.entity;

import javax.persistence.*;

/**
 *
 * @author David Buzatto
 */
@Entity
public class Produto {
    
    @Id
    @GeneratedValue
    private Long id;
    
    @Column( 
        length = 30,
        nullable = false
    )
    private String nome;
    
    @Column( 
        length = 50,
        nullable = false
    )
    private String descricao;
    
    private Double preco;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getDescricao() {
        return descricao;
    }

    public void setDescricao(String descricao) {
        this.descricao = descricao;
    }

    public Double getPreco() {
        return preco;
    }

    public void setPreco(Double preco) {
        this.preco = preco;
    }
    
}
package usandohibernate.entity;

/**
 * Enumeração das entidades.
 *
 * @author David Buzatto
 */
public enum EntityEnum {
    
    // entidades
    
    /**
     * Cliente.
     */
    CLIENTE( Cliente.class ),
    
    /**
     * Produto.
     */
    PRODUTO( Produto.class );
    
    
    private Class entity;
    
    EntityEnum( Class entity ) {
        setEntity( entity );
    }
    
    private void setEntity( Class entity ) {
        this.entity = entity;
    }
    
    public Class getEntity() {
        return entity;
    }
    
}
package usandohibernate.hibernate;

import org.hibernate.*;
import org.hibernate.cfg.*;
import usandohibernate.entity.*;

/**
 * Fábrica de sessões do hibernate.
 *
 * Utiliza uma enumeração de classes anotadas para popular a configuração.
 *
 * @author David Buzatto
 */
public class HibernateFactory {
    
    // fábrica de sessões
    private static final SessionFactory factory;
    
    /* 
     * AnnotationConfiguration, responsável em armazenar as configurações
     * das classes anotadas.
     */
    private static final AnnotationConfiguration config;
    
    /*
     * Permite que as sessions associadas sejam locais a thread que a está executando.
     */
    private static final ThreadLocal< Session > threadLocal = 
            new ThreadLocal< Session >();
    
    // bloco de inicialização estático (executado apenas UMA vez)
    static {
        
        // cria a AnnotationConfiguration, evitando uso do arquivo hibernate.cfg.xml
        config = new AnnotationConfiguration();
        
        // adiciona as classes anotadas
        EntityEnum[] entities = EntityEnum.values();
        
        for ( int i = 0; i < entities.length; i++ ) {
            config.addAnnotatedClass( entities[ i ].getEntity() );
        }
        
        // cria a factory
        factory = config.buildSessionFactory();
        
    }
    
    public SessionFactory getFactory() {
        
        return factory;
        
    }
    
    public AnnotationConfiguration getConfig() {
        
        return config;
        
    }
    
    public Session getSession() {
        
        Session session = factory.openSession();
        threadLocal.set( session );
        return factory.openSession();
        
    }
    
}
package usandohibernate.dao;

import java.util.*;
import org.hibernate.*;
import usandohibernate.entity.*;

/**
 *
 * @author David Buzatto
 */
public class ClienteDAO< T extends Cliente > {
    
    private Session session;
    private Class classe = Cliente.class;
    
    public ClienteDAO( Session session ) {
        
        this.session = session;
        
    }
    
    public void adiciona( T obj ) throws HibernateException {
        
        this.session.save( obj );
        
    }
    
    public void remove( T obj ) throws HibernateException {
        
        this.session.delete( obj );
        
    }
    
    public void atualiza( T obj ) throws HibernateException {
        
        this.session.update( obj );
        
    }
    
    public T procuraPorId( Long id ) throws HibernateException {
        
        return ( T ) this.session.load( classe, id );
        
    }
    
    public List< T > procuraPorNome( String nome ) throws HibernateException {
        
        Query query = this.session.createQuery(
                
                "FROM usandohibernate.entity.Cliente " +
                "WHERE nome LIKE ? "
                
        );
        
        query.setString( 0, nome );
        
        return query.list();
        
    }
    
    public List< T > procuraPorSobrenome( String sobrenome ) throws HibernateException {
        
        Query query = this.session.createQuery(
                
                "FROM usandohibernate.entity.Cliente " +
                "WHERE sobrenome LIKE ? "
                
        );
        
        query.setString( 0, sobrenome );
        
        return query.list();
        
    }
    
    public List< T > listaTudo() throws HibernateException {
        
        return this.session.createCriteria( classe ).list();
        
    }
    
    public List< T > listaPagina( int inicio, int quantia ) 
            throws HibernateException {
        
        return this.session.createCriteria( classe ).
               setMaxResults( quantia ).setFirstResult( inicio ).list();
        
    }
    
}
package usandohibernate.dao;

import java.util.*;
import org.hibernate.*;
import usandohibernate.entity.*;

/**
 *
 * @author David Buzatto
 */
public class ProdutoDAO< T extends Produto > {
    
    private Session session;
    private Class classe = Produto.class;
    
    public ProdutoDAO( Session session ) {
        
        this.session = session;
        
    }
    
    public void adiciona( T obj ) throws HibernateException {
        
        this.session.save( obj );
        
    }
    
    public void remove( T obj ) throws HibernateException {
        
        this.session.delete( obj );
        
    }
    
    public void atualiza( T obj ) throws HibernateException {
        
        this.session.update( obj );
        
    }
    
    public T procuraPorId( Long id ) throws HibernateException {
        
        return ( T ) this.session.load( classe, id );
        
    }
    
    public List< T > procuraPorNome( String nome ) throws HibernateException {
        
        Query query = this.session.createQuery(
                
                "FROM usandohibernate.entity.Produto " +
                "WHERE nome LIKE ? "
                
        );
        
        query.setString( 0, nome );
        
        return query.list();
        
    }
    
    public List< T > procuraPorDescricao( String descricao ) throws HibernateException {
        
        Query query = this.session.createQuery(
                
                "FROM usandohibernate.entity.Produto " +
                "WHERE descricao LIKE ? "
                
        );
        
        query.setString( 0, descricao );
        
        return query.list();
        
    }
    
    public List< T > procuraPorPreco( Double preco ) throws HibernateException {
        
        Query query = this.session.createQuery(
                
                "FROM usandohibernate.entity.Produto " +
                "WHERE preco = ? "
                
        );
        
        query.setDouble( 0, preco );
        
        return query.list();
        
    }
    
    public List< T > listaTudo() throws HibernateException {
        
        return this.session.createCriteria( classe ).list();
        
    }
    
    public List< T > listaPagina( int inicio, int quantia ) 
            throws HibernateException {
        
        return this.session.createCriteria( classe ).
               setMaxResults( quantia ).setFirstResult( inicio ).list();
        
    }
    
}
package usandohibernate;

import org.hibernate.*;
import usandohibernate.dao.*;
import usandohibernate.entity.*;
import usandohibernate.hibernate.*;

/**
 *
 * @author David Buzatto
 */
public class Testes {
    
    public static void main( String[] args ) {
        
        Produto p = new Produto();
        p.setNome( "arroz" );
        p.setDescricao( "comida..." );
        p.setPreco( 3.5 );
        
        Cliente c = new Cliente();
        c.setNome( "david" );
        c.setSobrenome( "buzatto" );
        
        Session session = null;
        Transaction t = null;
        
        try {
            
            session = new HibernateFactory().getSession();
            t = session.beginTransaction();
            
            new ProdutoDAO( session ).adiciona( p );
            new ClienteDAO( session ).adiciona( c );
            
            t.commit();
            
        } catch ( HibernateException exc ) {
            
            // tratar excessões específicas aqui
            
            if ( t != null )
                t.rollback();
            
        } finally {
            
            if ( session != null )
                session.close();
            
        }

        
    }
    
}

Aguardo resposta!

1 Resposta

T

eu acho q vc deve no construtor da dao instanciar o session e dar um close nele em cada chamada de metodo

Criado 15 de março de 2007
Ultima resposta 30 de mai. de 2007
Respostas 1
Participantes 2