Spring Data JPA repositories use in EJB timer causes TransactionRequiredException

前端 未结 2 1939
醉话见心
醉话见心 2020-12-15 01:15

I would like to use spring data repositories in my Java EE project. I use:

  • WildFly 10.0.0
  • Hibernate 5.0.7
  • Spring Data JPA 1.10.6
  • C
2条回答
  •  萌比男神i
    2020-12-15 01:49

    Short answer

    The repository initialization breaks the transaction. Initialize the repository beforehand, in a different Thread/transaction by adding @Eager to your repository instances.

    Explanation

    Spring Data repository instances are @ApplicationScoped and initialized on demand. The Thread (and transaction) that performs the first access to the repository is used for initialization.

    Spring Data JPA repository initialization does a couple of things, one of them is trying to figure out, whether you have provided named queries for repository query methods. Unfortunately, JPA does not provide an API to check whether a named query exists, so we rely on EntityManager.createNamedQuery(…). If there's no named query, EntityManager throws an exception and aborts the transaction.

    In a later stage, your EJB method uses the EntityManager within the same Thread (and transaction). It checks for an active transaction. Because the transaction is marked for rollback-only, you see the exception.

    Workaround

    Add @Eager to your repository declaration. The Spring Data CDI extension will initialize the repository on startup:

    @Eager
    public interface TestRepository extends CrudRepository {
        // …
    }
    

    Hint

    You don't require @Repository on TestRepository. Spring Data picks up the repository by picking up beans that are descendants from org.springframework.data.repository.Repository or plain interfaces annotated with @RepositoryDefinition.

    The transaction manager properties in your persistence.xml are not required, WildFly already configures the persistence context with the required settings.

    References:

    • DATAJPA-724
    • DATAJPA-617
    • Strange exception on inital request to Repository when using Spring Data JPA with EJB/CDI

提交回复
热议问题