Расширение 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
Это может работать с EAP 7.1
@Dependent
@PersistenceContext
private EntityManager entityManager;