Transaction required exception on execute update for JPQL update query

14,374

Solution 1

You are using an EntityManager to get the Named Queries and also using an (what I think is) injected UserTransaction.

See that the error message says "...Query object obtained through non-transactional access...". This means you are getting the "NamedQuery" through non-transactional access, because the EntityManager is not in the same transaction as _ut. So, you first join the EntityManager to the UserTransaction then you get and execute the query.

Finally your block should look like:

@PersistenceContext(unitName = "myPU")
EntityManager em;

@Inject
UserTransaction ut;

public void doSomeStuff()
{
    ut.begin();
    em.joinTransaction();

    em.createNamedQuery("query1").executeUpdate();

    ut.commit();
}

Solution 2

The problem does not come from your method implementation but from your execution context.
All method that update database must be executed within an opened transaction. The way you ensure that depends on the way you manage transaction. If transactions are user-managed you have to explicitly retrieve and join an existing transaction or open a new one. If it's container-managed just add @transactional annotation on your method or ensure that there is a method in your call hierarchy holding the annotation.

Here you're using user-managed transactions in a container-managed transaction context (see "container-managed transactional EntityManager" in your error message). You shouldn't so begin and commit / rollback yourself the transactions. If you want to do so, just retrieve an application-managed EntityManager to be able to properly access to JTA transactions.

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

Share:
14,374
Admin
Author by

Admin

Updated on June 15, 2022

Comments

  • Admin
    Admin almost 2 years

    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 of a container-managed transactional EntityManager

    Code: (_ut is a 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 would be greatly appreciated.

    Thanks.