Eu tenho uma aplicação web que usa Hibernate sem JPA, que faz login no banco server, mas, em tempo de execução as vezes preciso executar uma consulta no banco do cliente. Eu fiz alguma modificações na minha classe da fabrica de sessões do hibernate, mas, se estou em server e outra pessoa entra e consulta a base cliente altera a minha sessão no hibernate.
E se você enviar uma sessão para cada vez que um novo usuário requisitar um acesso aos dados? Você pode requisitar essa sessão nova e guardá-la nas suas classes de Business. Algo do tipo:
public class ConexaoHibernate {
private static SessionFactory sessionFactory = null;
// RETORNA UMA NOVA SESSÃO ABERTA PARA O SERVIDOR SELECIONADO.
public static Session getSession(String servidor) throws HibernateException {
Configuration configuration = new AnnotationConfiguration().configure("hibernate.cfg.xml");
config.setProperty("hibernate.connection.url", servidor);
sessionFactory = configuration.buildSessionFactory();
return sessionFactory.openSession();
}
Uma classe de Serviços pode ser definida da seguinte forma:
public class ServicosDisponiveis {
private Session currentSession = null;
/* RECEBO, NA HORA DA INSTÂNCIA DO OBJETO, A SESSÃO QUE ABRIREMOS. */
public ServicosDisponiveis(Session currentSession) {
this.currentSession = currentSession;
}
public String retornaUmValorQualquer() {
/* FAZ QUALQUER OPERAÇÃO QUE BUSCA DADOS, USANDO
A SESSION QUE OBTIVEMOS NA INSTÂNCIA DA CLASSE. */
return "Qualquer valor";
}
}
E, nas classes de controle das suas páginas, pode existir algo do tipo:
/* CRIA UMA NOVA SESSÃO, DEPENDENDO DO NOME DO SERVIDOR QUE VOCÊ PASSA POR PARÂMETRO. */
Session currentSession = ConexaoHibernate.getSession("nome do seu servidor");
/* CRIA UMA INSTÂNCIA DA SUA CLASSE DE BUSINESS COM A SESSÃO QUE FOI ABERTA. */
ServicosDisponiveis servicosDisponiveis = new ServicosDisponiveis(currentSession);
/* REALIZA AS OPERAÇÕES NA BASE DE DADOS DEPENDENDO DAQUELA SESSÃO. */
String valorQualquer = servicosDisponiveis.retornaUmValorQualquer();
Seria algo assim que você está procurando?
Abraços!
Que tal se você fizer assim? Vou fazer um exemplo simples com alunos de várias faculdades. Você escolhe qual a faculdade na sua página e ele conecta a um determinado servidor de dados.
Classe de domínio
[code]@Entity @Table(name=“ALUNOS”, schema=“DBO”)
public class Aluno implements Serializable { @Id
private Long ID; @Column(name=“NOME”)
private String nome;
private Session currentSession;
public ServicosAluno(Session currentSession) {
this.currentSession = currentSession;
}
public Aluno recuperarAlunoPorID(Long alunoID) throws HibernateException {
PersistenciaAluno persistenciaAluno = new PersistenciaAluno(currentSession);
return persistenciaAluno.recuperarUnico(alunoID);
}
}[/code]
Não sei se você tá trabalhando com JSP/Servlet ou com alguma framework mas, na classe de controle, você faz assim:
4. Classe de controle
String servidor = ""; /* suponhamos que você escolha o servidor na página e atribua a esta variável. */
Session currentSession = null;
currentSession = ConexaoHibernate.getSession("PUC" /* no caso, é nossa variável que vai como parâmetro */ );
ServicosAluno servicosAluno = new ServicosAluno(currentSession);
Aluno alunoDaPucComID100 = servicosAluno.recuperarAlunoPorID(100);
currentSession.close();
currentSession = ConexaoHibernate.getSession("USP" /* no caso, é nossa variável que vai como parâmetro */ );
ServicosAluno servicosAluno = new ServicosAluno(currentSession);
Aluno alunoDaUspComID100 = servicosAluno.recuperarAlunoPorID(100);
currentSession.close();
Funciona, mas, eu vi que tem um lag em cada consulta, pois, ele fecha e abre novamente a session.
[ ]'s
DTA![/quote]
É, era de se esperar isso. O que acontece é que, a cada vez que você requisita uma nova conexão, ele dá um build na SessionFactory (o lag tá aqui) e cria uma nova Session. E se fizer da seguinte maneira:
O usuário da PUC começa a acessar o sistema. Você requisita uma conexão nova pra ele e guarda em uma sessão do browser para que ele faça uso de uma session só para ele;
O usuário da EFEI começa a acessar o sistema. Você requisita uma conexão nova pra ele e guarda em uma sessão do browser para que ele faça uso de uma session só para ele.
ou, senão, você pode modelar a sua ConexaoHibernate de modo que seja um singleton e, a cada vez que mudar o servidor, aí sim ele dê um build na sessionFactory novamente! Algo do tipo:
[code]public class ConexaoHibernate {
private static ConexaoHibernate conexaoHibernate = new ConexaoHibernate();
public static ConexaoHibernate getInstance() { return conexaoHibernate; }
private ConexaoHibernate() {
setServidorAtual("");
}
private String servidorAtual;
public String getServidorAtual() { return servidorAtual; }
private void setServidorAtual(String servidorAtual) { this.servidorAtual = servidorAtual; }
private SessionFactory sessionFactory;
private Session currentSession;
public Session getNewSession(String servidor) throws HibernateException {
/* SE O SERVIDOR FOR DIFERENTE, AÍ SIM INSTANCIA UMA NOVA SESSIONFACTORY COM SEUS DADOS.*/
if (!servidor.equals(servidorAtual)) {
servidorAtual = servidor;
Configuration configuration = new AnnotationConfiguration().configure("hibernate.cfg.xml");
configuration.setProperty("hibernate.connection.url", servidorAtual);
sessionFactory = configuration.buildSessionFactory();
}
if (currentSession == null) {
currentSession = sessionFactory.openSession();
}
return currentSession;
}
}[/code]
Algo do tipo [fiz no olho, mas a ideia é por aí]. O que acha?
Abraços!
[quote=BMuniz]Eu vou tentar salvar a session do hibernate dentro da sessão do browser. Pois não posso ter o lag do singleton na aplicação.
Assim, que eu conseguir implementar te retorno, aqui.
Obrigadão
[]'s[/quote]
Esse “lag” que é gerado será causado em ambas as situações. Coloca o breakpoint na sua aplicação na linha do ConexaoHibernate que tem o comando buildSessionFactory(). Você vai ver o tempo de resposta até ele criar essa sessão. Não importa se você salve a sessão no browser ou use o Singleton para gerar sessões, esse lag existirá toda vez que você precisar de uma sessão para um novo servidor. Portanto, veja qual das duas te agrada mais e mãos à obra!