JBoss EAP 7.1 Spring-Data-JPA CDI 扩展

Car*_*ary 5 spring hibernate jpa spring-data-jpa jboss-eap-7

我们有一个使用 Spring Data JPA 存储库注入 EJB 的应用程序。春天org.springframework.data.jpa.repository.cdi.JpaRepositoryExtension有魔力。

它在 CDI 中查找 EntityManager,保存它以供以后使用,使用注释查找 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>)
Run Code Online (Sandbox Code Playgroud)

这最终导致...

org.springframework.data.jpa.repository.cdi.JpaRepositoryExtension.createRepositoryBean(Class<?>, Set<Annotation>, BeanManager)
Run Code Online (Sandbox Code Playgroud)

...抛出:

javax.enterprise.inject.UnsatisfiedResolutionException:无法使用限定符 [@javax.enterprise.inject.Default()、@javax.enterprise.inject.Any()] 解析“javax.persistence.EntityManager”的 bean。在 org.springframework.data.jpa.repository.cdi.JpaRepositoryExtension.createRepositoryBean(JpaRepositoryExtension.java:120) 在 org.springframework.data.jpa.repository.cdi.JpaRepositoryExtension.afterBeanDiscovery(JpaRepositoryExtension.java:96)


有没有人成功地将 Spring Data JPA 部署到 JBoss EAP 7.1 或 WildFly 11+ 上并获得在 CDI 中创建的 JPA 存储库?

编辑:我有一个在 EAP 6.2/3/4 中运行良好的 CDI Producer:

    @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 ;
    }
Run Code Online (Sandbox Code Playgroud)

Car*_*ary 1

我的问题的解决方案是两个小改变:

  • 将 @ApplicationScoped 添加到生产者类。显然,WELD 不再看到 @Producer 注释并在没有此注释的情况下处理生产者类(我认为),因为默认范围是 @Dependent。
  • 从 createEntityManager(...) 生产者方法中删除 @PersistenceContext 和参数,而是引用其中的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() ;
    }
}
Run Code Online (Sandbox Code Playgroud)