We have an app that uses Spring Data JPA repositories to inject into EJB's. Spring's org.springframework.data.jpa.repository.cdi.JpaRepositoryExtension
does the magic.
It looks for an EntityManager in CDI, saves it for later use, looks for Spring Data JPA repositories using the @Repository
annotation, and saves their types for later use. When CDI is initialized, JpaRepositoryExtension::afterBeanDiscovery
runs and to do the proper bean creation and insertion into CDI. This has worked perfectly under JBoss EAP 6.2/6.3/6.4.
JBoss EAP 7.1 is built on WildFly 11 and the Hibernate version is now 5.1. The JPA bootstrap code has been restructured in JBoss and the Hibernate JPA provider. Due to this restructuring the EntityManager is not in CDI at the time that this runs:
org.springframework.data.jpa.repository.cdi.JpaRepositoryExtension.processBean(ProcessBean<X>)
This eventually causes...
org.springframework.data.jpa.repository.cdi.JpaRepositoryExtension.createRepositoryBean(Class<?>, Set<Annotation>, BeanManager)
...to throw:
javax.enterprise.inject.UnsatisfiedResolutionException: Unable to resolve a bean for 'javax.persistence.EntityManager' with qualifiers [@javax.enterprise.inject.Default(), @javax.enterprise.inject.Any()]. at org.springframework.data.jpa.repository.cdi.JpaRepositoryExtension.createRepositoryBean(JpaRepositoryExtension.java:120) at org.springframework.data.jpa.repository.cdi.JpaRepositoryExtension.afterBeanDiscovery(JpaRepositoryExtension.java:96)
Has anyone successfully deployed Spring Data JPA onto JBoss EAP 7.1 or WildFly 11+ and gotten the JPA repositories created in CDI?
Edit: I have a CDI Producer that works fine in 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 ;
}
The solution to my problem was two small changes:
My producer class:
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() ;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With