[Resolvido] VRaptor 3 - DaoFactory, DaoInteceptor

Pessoal como eu utilizo os DaoFactory e DaoInteceptor no vraptor 3…

tem um pacote do Hibernate

mas não sei como utilizar

tentei utilizar a documentação, mas ainda não esta disponivel…

Se vc usa o Spring tá meio difícil de usar isso…
segunda feira sai o release rc-1 e vai ser só criar a classe:

public class CustomProvider extends SpringProvider {
    @Override
    public void registerCustomComponents(ComponentRegistry registry) {
        registry.register(SessionCreator.class, SessionCreator.class);
        registry.register(SessionFactoryCreator.class, SessionFactoryCreator.class);
    }
}

e trocar o provider pra ela no web.xml

<context-param>  
     <param-name>br.com.caelum.vraptor.provider</param-name>  
     <param-value>br.com.pacote.CustomProvider</param-value> 
</context-param>

Hoje você pode fazer o seguinte:

crie as classes:

@Component
public class MeuSessionCreator extends SessionCreator implements ComponentFactory<Session> {
    // delegate constructor
}
@Component
@ApplicationScoped
public class MeuSessionFactoryCreator extends SessionFactoryCreator implements ComponentFactory<SessionFactory> {
    // delegate constructor
}

Oi Rodrigo, blz? Só complementando a resposta do Lucas.

Entao, agora você nem precisa mais do DaoFactory pra ficar chamando toda hora getXXXDao, getYYYDao. Agora vc pode receber o Dao que vc quiser no construtor da sua lógica. Isso é bom pq seu código fica mais limpo, sem chamadas desnecessarias e fica tbm bem mais facil de testar (justamente pq agora vc ja recebe o dao direto). Entao, seu controller ficaria algo do tipo:

@Resource
public class MeuController {
    private VendaDao dao;

    public MeuController(VendaDao dao) {
        this.dao = dao;
    }

    public void novaVenda(Venda venda) {
        dao.adiciona(venda);
    }

}

Só que pro seu Dao poder ser injetado, você tem que anota-lo com @Component, entao:

@Component
public class VendaDao {
    private Session session;

    public VendaDao(Session session) {
        this.session = session;
    }

    public void adiciona(Venda venda) {
        session.save(venda);
    }
}

Esse código deve te levar a seguinte pergunta: “De onde vem a session?”. E aí entra a resposta do Lucas :).

[]'s

Sobre a mudança pro RC1 onde vou estender o Provider e fazer meu próprio. Será que não era mais legal fazer um ponto de extensão em forma de interface ao invés de herança? (não digo eu fazer um decorator em cima do SpringProvider implementando Provider)

Mas ter uma outra interface: CustomComponentsRegistrar (ou algo assim) que posso fazer simplesmente:

public class CustomProvider implements CustomComponentsRegistrar {
    public void registerCustomComponents(ComponentRegistry registry) {
        registry.register(SessionCreator.class, SessionCreator.class);
        registry.register(SessionFactoryCreator.class, SessionFactoryCreator.class);
    }
}

Aí os Providers específicos (Pico/Spring) chamam os meus CustomComponentsRegistrar (poderia até ter mais de um nesse caso). Um Observer mesmo.
A vantagem é não me forçar a usar herança (ou aquele decorator gigante cheio de delegates) e me deixar desacoplado da implementação de Provider (no exemplo do Lucas, o CustomProvider tem que saber que vou usar Spring)

Que acham?

Pessoal obrigado pelas respostas…

Vou tentar depois eu respondo se consegui…

Abraços…

Pessoal, infelizmente ainda não consegui, vou passar minhas classes para ver se tem algo errado…

[code]import org.hibernate.Session;
import org.hibernate.SessionFactory;

import br.com.caelum.vraptor.ioc.Component;
import br.com.caelum.vraptor.ioc.ComponentFactory;
import br.com.caelum.vraptor.util.hibernate.SessionCreator;

@Component
public class SessionProvider extends SessionCreator implements ComponentFactory{

private final SessionFactory factory;

public SessionProvider(SessionFactory factory) {
	super(factory);
	this.factory = factory;
	// TODO Auto-generated constructor stub
}

@Override
public Session getInstance(){
	return this.factory.getCurrentSession();
}

}[/code]

[code]import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;

import br.com.caelum.vraptor.ioc.ApplicationScoped;
import br.com.caelum.vraptor.ioc.Component;
import br.com.caelum.vraptor.ioc.ComponentFactory;
import br.com.caelum.vraptor.util.hibernate.SessionFactoryCreator;

@Component
@ApplicationScoped
public class SessionFactoryProvider extends SessionFactoryCreator implements ComponentFactory {

private final SessionFactory factory;
private final Session session;
public SessionFactoryProvider(){
	this.factory = new AnnotationConfiguration().configure().buildSessionFactory();
	this.session = this.factory.openSession();
}

@Override
public SessionFactory getInstance(){
	return this.factory;
}

public Session getSession(){
	return this.session;
}

}[/code]

[code]
@Component
public class ClienteDao extends Dao {

private final Session session;

public ClienteDao(Session session){
	super(session, Cliente.class);
	this.session = session;
}

}[/code]

[code]import java.util.List;

import org.hibernate.Session;

public class Dao {
private final Session session;
private final Class classe;

protected Dao(Session session, Class<T> classe) {
	this.session = session;
	this.classe = classe;
}

public Session getSession(){
	return this.session;
}

public void adiciona(T o){ 
	this.session.save(o); 
}

public void adiciona(List<T> o){
	try { 
		for(T item : o){ 
			this.session.save(item); 
		} 
	}catch(Exception e){}
}

public void adicionar(List<T> o){ 
	for(T item : o){ 
		this.session.save(item); 
	} 
}

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

public void remove(List<T> o){ 
	try{ 
		for(T item : o){ 
			this.session.delete(item); 
		} 
	}catch(Exception e){}	
}

public void atualiza(T o){
	try{
		this.session.merge(o);
	}
	catch(Exception e){
		try{
			this.session.saveOrUpdate(o);
		}catch(Exception e1){
			this.session.save(o);
		}
	}
}

public void atualiza(List<T> o){
	for(T item : o){
		try
		{
			this.session.merge(item);
		}
		catch(Exception e){
			try{
				this.session.saveOrUpdate(item);
			}catch(Exception e1){
				this.session.save(item);
			}
		}
	}
}

@SuppressWarnings("unchecked")
public T procura(Long id){ 
	return (T) this.session.load(this.classe, id); 
}

@SuppressWarnings("unchecked")
public List<T> listaTudo(){ 
	return this.session.createCriteria(this.classe).list(); 
}

}[/code]

Pessoal consegui resolver…

O problemas estava no

com isso ele abria duas sessoes de uma só vez

e no

public Session getSession(){  
        return this.session;  
}

esse método não implementa o ComponentFactory

do meu SessionFactoryProvider

na verdade não sei o porque eu coloquei isso ai… :lol:

Abraços…