I get the exception in the logs:
javax.persistence.TransactionRequiredException: Executing an update/delete query
This is in the isNew = false
branch in updateSomething()
-method. I didn't spot exceptions from other branch.
I found something on stackoverflow about using entityManager.joinTransaction();
, but when I do this, I get another exception:
java.lang.IllegalStateException: Not allowed to join transaction on shared EntityManager
I would like to handle this correctly so that the updateSomething
method works. I'd also would like to know whether having nested @Transactional annotation is a good idea and what the effect of calling a transactional method from a transactional method is - I believe the inner transactional runs in its own transaction and commits to database.
Note: The HACK doesn't work I left it in as an example of what I've tried.
Idea: Would it help to do a entityManager.flush()
after every update (an update using native SQL)?
@Transactional
public boolean generateLogsComposite() {
Connection conn = getConnection();
writeSomeData(conn);//write some data using a separate connection
boolean isNew = checkSomeData();//The check works with the data from writeSomeData although not using he connection conn
if(isNew) {
generateEmail(conn);//Calls a stored procedure on connection conn.
updateRunEnvOnEmail(emailId, runEnv);
//Now the data from generateEmail and updateRunEnvOnEmail is present
} else {
updateSomething();//has a javax.persistence.TransactionRequiredException: Executing an update/delete query
}
}
private void joinTransaction() {
try {
//HACK vs javax.persistence.TransactionRequiredException: Executing an update/delete query
entityManager.joinTransaction();
logger.debug("Joined transaction successfully");
} catch(Throwable t) {
//java.lang.IllegalStateException: Not allowed to join transaction on shared EntityManager
}
}
@Transactional
public void updateRunEnvOnEmail(Long emailId, String runEnv)
{
try
{
//HACK vs javax.persistence.TransactionRequiredException: Executing an update/delete query
joinTransaction();
Query query = entityManager
.createNativeQuery("update XXX.EMAIL e set e.RUN_ENVIRONMENT = :runEnv where e.EMAIL_ID = :emailId");
query.setParameter("runEnv", runEnv);
query.setParameter("emailId", emailId);
query.executeUpdate();
} catch (Exception e)
{
logger.debug("Error while updating RUN_ENVIRONMENT on Email : "
+ emailId + " ::: " + e);
}
}
@Transactional
public void updateSomething()
{
try
{
//HACK vs javax.persistence.TransactionRequiredException: Executing an update/delete query
joinTransaction();
Query query = entityManager
.createNativeQuery("update something");
query.executeUpdate();
} catch (Exception e)
{
logger.debug("Error while updating something",e);
}
}