Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent flush of EntityManager when selecting a given data

I am developping a JPA application (with hibernate), and I am fighting with the AutoFlush feature.

By default, whenever we process a query on any entity, the complete EntityManager is flushed. This is ok in most cases : We want JPA to process queries against an up-to-date DB.

However, it happens that we also store some functional parameters in our DB. This is completely separated from our core business model, and we don't want that selecting parameters we flushed the EM : Fetch of parameters can happen quite deep in the process and we loose the control of flushing EM when we know it;as ok.

Indeed, this causes some DB constraint exception : The data model is not consistent yet (in the middle of a process), and selecting a parameter forces the flush of this data model.

I am considering adding a second entityManager, just of the parameters, but I find it a bit overkill.

Could it be solved more easily ? With isolation level on the Parameters DAO, so that Parameters are processed in a separate transaction ?

like image 483
Raphael Jolivet Avatar asked Sep 30 '22 17:09

Raphael Jolivet


2 Answers

This can be solved with JTA transactions, but you need a JTA transaction manager. If you are running in a Java EE application server than you already have JTA support. If you run a Spring based application you need to include a stand-alone TM, like Bitronix.

JTA then allows you to enlist multiple connections even for the same DB (but with multiple data sources from the same thread) in a single global transaction. So you entity manager will enlist one connection and then you could open a new connection from your XA connection pool (provided by your JTA transaction manager, like Bitronix) and save the functional parameters.

Those 2 enlisted connections will be isolated, so changes in one won't be available in the second until after the transaction is committed.

If the functional parameters don't need to be saved through JPA, it's easier to use Spring JDBC for this task. Otherwise you need two entity managers and that will complicate your settings even more.

like image 55
Vlad Mihalcea Avatar answered Oct 09 '22 23:10

Vlad Mihalcea


I. If you use JTA:

  1. Try using a new transaction in the ParametersDAO. This way your managed entities in the outer service will not be managed in the inned DAO (IMHO!). The disadvantage is that when your ParametersDAO returns, the transaction will commit (if that is not desired, you could use a Statefull EJB, but this one seems like an overkill to me).
  2. Otherwise, having a second EntityManager does not seem such an overkill to me.

II. If you use RESOURCE-LOCAL:

If you are in an Application-Managed environment (transaction-type="RESOURCE_LOCAL"), simply get another EntityManager from the EntityManagerFactory (similarly with having a second EntityManager).

like image 1
V G Avatar answered Oct 09 '22 22:10

V G