Necessito em alguns pontos de um sistema utilizar outro banco de dados em paralelo ou seja outra session factory do hibernate que nao seja a padrao carregada pelo pacote vraptor-plugin-hibernate4-1.0.0.jar.
Em resumo meu banco padrao é um banco oracle e algumas telas tenho que acessar um banco de dados db2 , estou usando o hibernate 4.1.3, o guice como container de DI ,vraptor 3.4.1 , entao o que fiz foi o seguinte :
criei um hibernate.cfg.rdo.xml (nao padrao)
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.DB2Dialect</property>
<property name="hibernate.connection.driver_class">com.ibm.db2.jcc.DB2Driver</property>
<property name="hibernate.connection.url">jdbc:db2://localhost:50000/database</property>
<property name="hibernate.connection.username">user</property>
<property name="hibernate.connection.password">password</property>
<property name="hibernate.connection.provider_class">org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.c3p0.min_size">1</property>
<property name="hibernate.c3p0.max_size">20</property>
<property name="hibernate.c3p0.timeout">30</property>
<property name="hibernate.c3p0.idle_test_period">300</property>
<mapping class="app.Regional" />
</session-factory>
</hibernate-configuration>
a classe RdoSessionFactoryCreator :
@Component
@ApplicationScoped
public class RdoSessionFactoryCreator {
private SessionFactory sessionFactory;
private Configuration cfg;
private ServiceRegistry serviceRegistry;
public RdoSessionFactoryCreator() {
cfg = new Configuration().configure("hibernate.cfg.rdo.xml");
ServiceRegistryBuilder builder = new ServiceRegistryBuilder();
serviceRegistry = builder.applySettings(cfg.getProperties()).buildServiceRegistry();
}
@PostConstruct
protected void create() {
sessionFactory = cfg.buildSessionFactory(serviceRegistry);
}
@PreDestroy
protected void destroy() {
if (!sessionFactory.isClosed()) {
sessionFactory.close();
}
}
public SessionFactory getInstance() {
return sessionFactory;
}
}
e a classe RdoSessionCreator :
@Component
@RequestScoped
public class RdoSessionCreator {
private Session session;
private SessionFactory factory;
//To achando meio gambiarra injetar RdoSessionFactoryCreator em vez de SessionFactory
// e depois pegar com getInstance();
public RdoSessionCreator(RdoSessionFactoryCreator factoryCreator) {
factory = factoryCreator.getInstance();
}
@PostConstruct
public void create() {
session = factory.openSession();
}
@PreDestroy
public void destroy() {
if (session.isOpen()) {
session.close();
}
}
public Session getInstance() {
return session;
}
}
e em um repositório chamo assim :
@Component
public class RegionalRepositoryImpl implements RegionalRepository {
private Session session;
//To achando meio gambiarra injetar RdoSessionCreator em vez de Session
// e depois pegar com getInstance(); no mesmo caso acima
public RegionalRepositoryImpl(RdoSessionCreator sessionCreator){
this.session = sessionCreator.getInstance();
}
@SuppressWarnings("unchecked")
@Override
public List<Regional> listAll() {
Criteria criteria = session.createCriteria(Regional.class);
return criteria.list();
}
}
Tem algum modo mais elegante de fazer isso injetando direto nos construtores os carinhas certos em vez de ter que ficar pedindo getInstance() toda vez ??
Nunca trabalhei com algo mais avançado de DI no vraptor , vi algumas coisas de fazer a classe implementar Provider e com @Named pegar direto no construtor direto , usando a especificação , mas num entendi direito o que preciso fazer pra funcionar , algum ai pode me ajudar a refatorar ?? Do jeito que está até funciona , mas sei la , meio estranho ficar injetando desse jeito.
Agradeço a ajuda
