6
I’m having a bit of an unusual problem, but I’m looking for a solution.
I have a scenario where I have several databases (postgresql) allocated in several clients, all databases have the same structure, but with different records.
I have a java application with jpa
, ecliselink
and ejb 3
, ready and in operation, today in it I use the Entitymanager letting the container manage the transactions for me (CMT - Container Managed Transaction), so I do not need to keep giving Begin and commit, it solves when run in the best way.
Well, keeping this in mind, I need to continue using this structure and I cannot switch to manual mode (BTM - Bean Managed Transaction), I need to continue using CMT (for larger reasons). Researching and studying the concept a lot, I was able to realize the functionality of connecting in several bases with JTA, but that way I could not manage it by container(CMT), I would have to give Begin and commit. I will post the code that I managed to perform this function, if anyone knows how to leave the transaction as CMT following this reasoning basis I would appreciate.
The code below works, but is not running as CMT, only persists if you have Begin and commit:
@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class TestEntDAO {
private EntityManager em;
private EntityManagerFactory emf;
@PostConstruct
public void init() {
em = getEntityManager();
}
public EntityManager getEntityManager() {
Map props = new HashMap();
props.put(PersistenceUnitProperties.TRANSACTION_TYPE, "JTA");
props.put(PersistenceUnitProperties.JTA_DATASOURCE, dataSourceName()); // <- Aqui será injetado o cliente que está logado, pegando a base dele.
emf = Persistence.createEntityManagerFactory("testePU", props);
em = emf.createEntityManager();
return em;
}
public String dataSourceName(){
if(someCondition){
return "db1";
}else{
return "db2";
}
}
public salvar(Tabela tab){
em.persist(tab);
} //<-- quando termia esse método era para dar o commit automatico (CMT), mais não esta sincronizando as transações.
}
Someone who understands JPA well could help me?
Observing: If someone tells you to use several @PersistenceContext(unitName = "db1")
, I can not use this way, because if any IP goes outside or gives problem on some basis the application does not go up, giving a headache, also I tried to use the Multitenancy did not fit in this case.
The way to do this is this: set up multiple Units persistence and identify which one you want to use
@PersistenceContext(unitName = "db1")
. If you need to upload your application even with an unavailable database server, perhaps it would be better to search for this feature rather than another technique of using connections to multiple database servers. Which application server do you use? Perhaps the application server itself provides a setup for this.– Caffé
I tried to do this, turned glassfish3 upside down, if any connection fails it throws a connection allocation exception. thinking that you may have more than 50 @Persistencecontext created, imagine the headache, apart from the maintenance of this, in and out customer. Unviable.
– Luciano
Hmm I remembered now that I already had this need a few years ago (connect to N Database on N servers) and I ended up with the same code you posted: without using transaction managed by the container. And yet I had to create on the arm an Entitymanagerfactory pool for performance reasons. If you find a better solution, put it there and give me a touch please. Good luck!
– Caffé
If I get put here, it’s more complicated. Thanks.
– Luciano
Luciano, in its implementation data source is defined once at the startup of bean, soon your DAO would access only one of possible data sources. Is that really how it works? Or does the application use different fonts in the same execution, depending on some criteria? What is this criterion, that is, how the application decides which is the data source?
– utluiz