Transaction is not accessible when using JTA with JPA-compliant transaction access enabled

I have a Transaction Manager injected with @PersistenceContext context annotation. Every time I'm trying to start the transaction with em.getTransaction().begin I got an exception with the error message

Transaction is not accessible when using JTA with JPA-compliant transaction access enabled

I know that I should inject UserTransaction or use @Transactional annotation but I want to know the reason for such behavior.


I think you should inject a container managed transaction.

Something like:

@Resource
private UserTransaction transaction;

public method() {
  try {
     transaction.begin();
     ...do some persistence...
     transaction.commit();
  } catch (Exception e) {
     transaction.rollback();
  }
}

OR

if you don't need such control you can use @Transaction annotation on your method.

Hope it helps.


I had the very same issue but problem lied elsewhere...

So the stack: I was using Wildfly server , postgresql, and JPA

At first, my persistence.xml was configured to use RESOURCE_LOCAL transactions e.g.

<persistence-unit name="unit" transaction-type="RESOURCE_LOCAL">

and I had a problem that even when the method was marked @Transactional it was not doing any rollbacks when error occured, yet saving worked fine.

So then I decided to use transaction-type JTA instead of RESOURCE_LOCAL so that the container manages the transactions.

When I changed my persistence.xml to this, it was still not working

<persistence-unit name="unit" transaction-type="JTA">
    <jta-data-source>java:jboss/datasources/unit</jta-data-source>

and was throwing the very error that is in the title of this question.

My problem was, how I was creating the EntityManager, this is how it was defined

@Produces
@PersistenceContext
private static EntityManager em = Persistence.createEntityManagerFactory(UNIT_NAME).createEntityManager()

The solution? I had to remove the annotation @PersistenceContext

P.s. for JTA transactions do not forget to tell wildfly about the datasource for example via CLI like this

data-source add --jndi-name=java:jboss/datasources/unit --name=MyDb --connection-url=jdbc:postgresql://localhost:5432/postgres  --driver-name=postgresql  --user-name=username --password=password