Vraptor 3 duas sessions factories

Tenho o seguinte código

@ApplicationScoped
@Resource
public class SessionFactoryCreator implements ComponentFactory<SessionFactory> {
	private final SessionFactory factory;
 
	public SessionFactoryCreator() {
		this.factory = HibernateUtilities.getSessionFactory();
	}
 
	public SessionFactory getInstance() {
		return this.factory;
	}
 
	@PreDestroy
	public void destroy() {
		if (!this.factory.isClosed())
			this.factory.close();
	}
 
}

Repositorio

public class CategoriasImpl implements Categorias {
	private Session session;

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

Funciona ok, porém minha aplicação agora tem de acessar uma segunda base. Então eu teria duas SessionFactory, algo assim

public class CategoriasImpl implements Categorias {
	private Session sessionPrimaria;
	private Session sessionSecundaria;

	public CategoriasImpl(Session sessionPrimaria, Session sessionSecundaria) {
		this. sessionPrimaria = sessionPrimaria;
		this. sessionSecundaria = sessionSecundaria;
	}
...
}

Gostaria de saber se:
a) tem uma maneira de fazer isso já prevista?
b) caso contrário, quando o objeto ‘CategoriasImpl’ é criado o vraptor chama duas vezes o método getInstance, certo? Eu tenho como saber quem está chamando? se eu souber eu teria como retornar o SessionFactory certo…

[]s

PS. não fico feliz com isso, mas eu tenho de usar duas bases

provavlmente não tem… tenta esse approche

[code]@Component
@ApplicationScoped
public class SessionFactoryCollections {
private final SessionFactory base1;
private final SessionFactory base2;

public SessionFactoryCollections() {
    this.base1= HibernateUtilities.getSessionFactory1();
    this.base2= HibernateUtilities.getSessionFactory2();
}

public SessionFactory getFactory1() {
    return base1;
}

public SessionFactory getFactory2() {
    return base2;
}

 @PreDestroy  
 public void destroy() {  
     if (!this.base1.isClosed())  
         this.base1.close();  
     if (!this.base2.isClosed())  
         this.base2.close();  
 }

}[/code]

mesma ideia para as sessions… e assim por diante

Funcionou
Valeu pela idéia não tinha visto essa possibilidade.

Criei um SessionFactoryCollection e um SessionCollection e usando o ComponentFactory do vraptor, injeto os dois no meu Factory [que cria os meus repositorios], e assim o factory passa as sessions para quem precisa de uma ou das duas e não precisei mexer em nada nos repositorios e todo mundo ficou feliz, ficou bem transparente.

[]s

Olá Edufa,

está programado pra gente fazer um jeito de ter duas componentFactories pro mesmo componente…
mas fica meio difícil decidir algo que fique usável (sem ter que anotar parâmetros de construtor, por exemplo)

De qualquer forma essa solução é boa =)

[]'s

Esta aqui:

mas sera que solucoes como essa ja nao sao suficientes?

[quote=lucascs]Olá Edufa,

está programado pra gente fazer um jeito de ter duas componentFactories pro mesmo componente…
mas fica meio difícil decidir algo que fique usável (sem ter que anotar parâmetros de construtor, por exemplo)

De qualquer forma essa solução é boa =)

[]'s[/quote]

Nesse caso eu vejo uma solução bem mais simples. Ele pode criar uma classe wrapper para injetar a session que ele quiser. Até porque nesse exemplo do Lavieri sempre serão enjetados as duas. Pode haver casos que ele precise apenas de uma.

[quote=garcia-jj][quote=lucascs]Olá Edufa,

está programado pra gente fazer um jeito de ter duas componentFactories pro mesmo componente…
mas fica meio difícil decidir algo que fique usável (sem ter que anotar parâmetros de construtor, por exemplo)

De qualquer forma essa solução é boa =)

[]'s[/quote]

Nesse caso eu vejo uma solução bem mais simples. Ele pode criar uma classe wrapper para injetar a session que ele quiser. Até porque nesse exemplo do Lavieri sempre serão enjetados as duas. Pode haver casos que ele precise apenas de uma.[/quote]

na verdade não é injetado nenhuma das 2… é injetado um “Facade” de onde pode ser acessado a factory que desejar… factorys são ApplicationScoped, então tanto faz instanciar…

Quando chegar nas Session, é preciso só instanciar quando alguem der um getSession1() ou getSession2()

@lucascs, @garcia-jj, @Paulo Silveira, @Lavieri

Realmente funcionou e resolveu o problema, mas no meu caso eu preciso ter as duas Sessions em quase todas as vezes, pq uma delas é para um base de logs então quase tudo é logado sendo assim em todas as requisições eu uso as duas sessions.

Já em outros casos não sei se essa saida resolverei tão bem e tão elegantemente.

Pensando alto, as situações.

[1] Situação:
Preciso sempre ou quase sempre de duas implementações e eu sei quando eu preciso de uma ou de outra,

Solução:
A solução do @Lavieri funciona.

[2] Situação:
Tenho de decidir se uso um ou outra implementação e isso será constante para o escopo

Solução:
no cookbook tem como fazer.
http://vraptor.caelum.com.br/cookbook/componentfactory-como-seletor-de-implementacoes/

[3] Situação
Tenho de decidir se uso um ou outra implementação e isso muda dentro do escopo

Solução:
não achei um exemplo, de qq forma acho q as duas soluções acima resolvem a maioria dos casos.
Nesse caso o getInstance(), tem de resolver se entrega uma ou outra implementação, ele teria de saber mais sobre quem está pedindo, com anotações por exemplo, sei lá, para poder instanciar a implementação correta … pensando alto, rs

Não sou nenhum especialista no vraptor, se falei alguma besteira desconsiderem, rs

[]s

sabendo ou não sabendo, eu escreveria a Session assim

[code]public class SessionCollecions {
private final SessionFactoryCollections factorys;
private Session session1;
private Session session2;

public SessionCollecions(SessionFactoryCollections factorys) {
    this.factorys = factorys;
}

public Session getSession1() {
    if (session1 == null)
        session1 = factorys.getSessionFactory1().openSession();
    return session1;
}

public Session getSession2() {
    if (session2 == null)
        session2 = factorys.getSessionFactory2().openSession();
    return session2;
}

@PreDestroy    
public void destroy() {    
      if (session1 != null && this.session1.isOpen())    
          this.session1.close();    
      if (session2 != null && this.session2.isOpen())    
          this.session2.close();    
} 

}[/code]