Transaction exception thrown during update execution for JPQL update request

I get this error when I try to run this code.

Error:

javax.persistence.TransactionRequiredException: executeUpdate is not supported for a Query object obtained through non-transactional access to a transactional container-managed EntityManager

Code: (_ut - UserTransaction object)

public void setMainCategory (Integer deptId, Integer catId) {

try { Query setmain = _entityManager.createNamedQuery("Category.setAsMain"); Query removeMain = _entityManager.createNamedQuery("Category.removeMain"); setmain.setParameter("categoryId", catId); Department d; d=_entityManager.find(Department.class, deptId); removeMain.setParameter("department", d); _ut.begin(); removeMain.executeUpdate(); _ut.commit(); _ut.begin(); setmain.executeUpdate(); _ut.commit(); } catch (Exception e) { e.printStackTrace(); } } 

I have other functions that are identical in implementation, and they do not throw this error.

Any suggestions are welcome.

Thanks.

+4
source share
3 answers

You are using the EntityManager to receive named queries, and also using (what I think) an inserted UserTransaction .

See what the error message says: "... Request object received via non-transactional access ...". This means that you get "NamedQuery" through non-transactional access, because the EntityManager not in the same transaction as _ut . So, first you attach the EntityManager to the UserTransaction , then receive and execute the request.

Finally, your block should look like this:

 @PersistenceContext(unitName = "myPU") EntityManager em; @Inject UserTransaction ut; public void doSomeStuff() { ut.begin(); em.joinTransaction(); em.createNamedQuery("query1").executeUpdate(); ut.commit(); } 
+3
source

The problem arises not from the implementation of your method, but from the execution context.
All methods that update the database must be executed as part of an open transaction. The way you guarantee depends on the way you manage your transactions. If the transactions are user-managed, you need to explicitly obtain and join an existing transaction or open a new one. If it is managed by the container, simply add the @transactional annotation to your method or make sure that there is an annotation in your call hierarchy containing the annotation.

Here you use user-managed transactions in the context of container-managed transactions (see "Transaction-Driven Transactional EntityManager" in the error message). You should not start and commit / roll back from transactions. If you want to do this, just get the application-driven EntityManager to be able to correctly access JTA transactions.

Wed http://docs.oracle.com/cd/E19226-01/820-7627/bnbqy/index.html

+1
source

According to the error message, I think the reason is that your order of transactions, you didn’t get Department d in the transaction, so statement d separated, then you want to directly update it, which will change the expression to be managed, JPA cannot do this. just move the find code in the transaction, I think everything will be fine.

0
source

All Articles