Расширение CDI JBoss EAP 7.1 Spring-Data-JPA

У нас есть приложение, которое использует репозитории Spring Data JPA для внедрения в EJB. Спринга org.springframework.data.jpa.repository.cdi.JpaRepositoryExtension делает магию.

Он ищет EntityManager в CDI, сохраняет его для дальнейшего использования, ищет репозитории Spring Data JPA, используя @Repository аннотации и сохраняет их типы для последующего использования. Когда CDI инициализируется, JpaRepositoryExtension::afterBeanDiscovery работает и для правильного создания и вставки bean-компонентов в CDI. Это отлично работает под JBoss EAP 6.2 / 6.3 / 6.4.

JBoss EAP 7.1 построен на WildFly 11, а версия Hibernate теперь 5.1. Код начальной загрузки JPA был реструктурирован в JBoss и провайдере Hibernate JPA. Из-за этой реструктуризации EntityManager не находится в CDI в то время, когда это выполняется:

org.springframework.data.jpa.repository.cdi.JpaRepositoryExtension.processBean(ProcessBean<X>)

Это в конечном итоге вызывает...

org.springframework.data.jpa.repository.cdi.JpaRepositoryExtension.createRepositoryBean(Class<?>, Set<Annotation>, BeanManager)

...бросать:

javax.enterprise.inject.UnsatisfiedResolutionException: невозможно разрешить bean-компонент для 'javax.persistence.EntityManager' с квалификаторами [@javax.enterprise.inject.Default(), @javax.enterprise.inject.Any()]. в org.springframework.data.jpa.repository.cdi.JpaRepositoryExtension.createRepositoryBean(JpaRepositoryExtension.java:120) в org.springframework.data.jpa.repository.cdi.JpaRepositoryExtension.afterBeanDisory:96)


Кто-нибудь успешно развернул Spring Data JPA на JBoss EAP 7.1 или WildFly 11+ и получил репозитории JPA, созданные в CDI?

Редактировать: у меня есть CDI Producer, который отлично работает в EAP 6.2/3/4:

    @Produces
    @Dependent
    @PersistenceUnit( unitName="** Our PU Name **" )
    private EntityManagerFactory entityManagerFactory;
.
.
.
    @Produces
    @RequestScoped
    @PersistenceContext( type = PersistenceContextType.EXTENDED )
    public EntityManager createEntityManager( EntityManagerFactory emf )
    {
        EntityManager em = emf.createEntityManager();
        return em ;
    }

2 ответа

Решение

Решением моей проблемы было два небольших изменения:

  • Добавьте @ApplicationScoped в класс производителя. По-видимому, WELD больше не видит аннотации @Producer и не обрабатывает класс производителя без этого (я думаю), поскольку областью действия по умолчанию является @Dependent.
  • Удалите @PersistenceContext и параметр из метода источника createEntityManager(...), вместо этого ссылаясь на него entityManagerFactory. Странно, что это работало даже с более ранней версией, поскольку @PersistenceContext "выражает зависимость от управляемого контейнером EntityManager...", о котором рявкнул новый WELD, так как параметром был EntityManagerFactory.

Мой продюсерский класс:

import javax.enterprise.context.ApplicationScoped ;
import javax.enterprise.context.Dependent ;
import javax.enterprise.context.RequestScoped ;
import javax.enterprise.inject.Disposes ;
import javax.enterprise.inject.Produces ;
import javax.persistence.EntityManager ;
import javax.persistence.EntityManagerFactory ;
import javax.persistence.PersistenceUnit ;


@ApplicationScoped
public class CdiConfig
{
    /*
     * Entity Manager Factory
     */
    @Produces
    @Dependent
    @PersistenceUnit(unitName = "stafftrack_data_access")
    private EntityManagerFactory entityManagerFactory ;


    /*
     * Entity Manager
     */
    @Produces
    @RequestScoped
    public EntityManager createEntityManager( )
    {
        EntityManager em = entityManagerFactory.createEntityManager() ;
        return em ;
    }


    public void close( @Disposes EntityManager entityManager )
    {
        entityManager.close() ;
    }
}

Вы можете попытаться использовать / добавить несколько аннотаций в ваш Entity Manager, которые могут решить эту проблему. Вы пробовали это:
@Produces
@Dependent
@PersistenceContext
private EntityManager entityManager;
Это может работать с EAP 7.1

Другие вопросы по тегам