Senhores,
Como tenho muito carinho por esse forum, e fui muitas vezes ajudado pelo mesmo, me sinto feliz em explicar como resolvi o problema. Não sei se essa minha solução é a melhor, para mim ficou legal, mas vamos lá… Vou me basear num exemplo para duas empresas(Empresa1 e Empresa2). Porém esse exemplo pode ser utilizado para mais de duas empresas.
Primeiro vamos precisar de uma SessionFactory para cada empresa:
Para Empresa1 criei a classe Empresa1DB onde vai configurar e retornar a SessionFactory desta empresa:
...
private static final SessionFactory sessionFactory;
private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
static {
try{
AnnotationConfiguration configuration = new AnnotationConfiguration();
configuration.addAnnotatedClass(modelo.Usuario.class);
configuration.addAnnotatedClass(modelo.Paciente.class);
//aqui é a unica mudança no meu caso para as SessioFactory pois mudo só onde está o Schema desejado
configuration.setProperty("hibernate.connection.url","jdbc:mysql://localhost/empresa1");
configuration.setProperty("hibernate.connection.driver_class", "com.mysql.jdbc.Driver");
configuration.setProperty("hibernate.connection.username", "root");
configuration.setProperty("hibernate.connection.password","root");
configuration.setProperty("hibernate.dialect","org.hibernate.dialect.MySQLDialect");
configuration.setProperty("hibernate.hbm2ddl.auto","update");
sessionFactory = configuration.buildSessionFactory();
}catch (Throwable t){
throw new ExceptionInInitializerError(t);
}
}
public static Session getInstance(){
Session session = (Session) threadLocal.get();
session = sessionFactory.openSession();
threadLocal.set(session);
return session;
}
public static void closeSession(){
sessionFactory.close();
}
public static SessionFactory getSessionFactory(){
return sessionFactory;
}
}
A mesma coisa fiz para Empresa2 só mudo a linha onde define o Schema para empresa2:
configuration.setProperty("hibernate.connection.url","jdbc:mysql://localhost/empresa2");
IMPORTANTE: Reparem que criei o método getSessionFactory() que retorna a SessionFactory construída nesta classe!
Agora vou utilizar meu LoginAction para fazer essa “escolha de Base de Dados”!!
Primeiramente na tela de login vou passar uma Strig como parâmetro na minha .jsp para identificar a empresa:
...
<input name="empresa" tabindex="3" maxlength=13 size=13/>
...
Passado a String com o nome da empresa que quero utilizar, a nossa LoginAction vai direcionar tudo:
...
public class LoginAction extends Action{
...
//Criei uma SessionFactory estatica que vai receber a SessionFactory da empresa escolhida
public static SessionFactory sessionFactory;
//recebendo o paremetro da .jsp
bd = request.getParameter("empresa");
System.out.println("Empresa Selecionada: "+bd);
//fazendo a comparação e nossa static sessionFactory vai receber a SessionFactory escolhida
//utilizamos o metodo getSessionFactory() que criamos anteriormente
if (bd.equals("Empresa1")){
sessionHibernate = Empresa1DB.getInstance();
sessionFactory = Empresa1DB.getSessionFactory();
}
if(bd.equals("Empresa2")){
sessionHibernate = Empresa2DB.getInstance();
sessionFactory = Empresa2DB.getSessionFactory();
}
...
Pronto!!! Agora nossa LoginAction está com a nossa SessionFactory escolhida!!
Agora é só chamar nossa SessionFactory toda vez que for abrir uma sessão, por exemplo:
...
Session sessionHibernate = LoginAction.sessionFactory.openSession();
Transaction transaction = sessionHibernate.beginTransaction();
UsuarioDAO dao = new UsuarioDAO(sessionHibernate);
dao.salva(usuario);
transaction.commit();
sessionHibernate.close();
...
Lembrando que na ação de Logoff ou no filtro de sessão expirada temos que encerrar nossa SessionFactory:
LoginAction.sessionFactory.close();
Não sei se consegui ser claro. Também não sei se essa é a melhor forma. Mas está funcionando e está aí para quem quiser usar.
Qualquer dúvida estou a disposição para ajudar
Abraço a todos!