问题
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 ;
}
回答1:
The solution to my problem was two small changes:
- Add @ApplicationScoped to the producer class. Apparently WELD no longer sees @Producer annotations and processes the producer class without this (I think) because the default scope is @Dependent.
- Remove @PersistenceContext and the parameter from the createEntityManager(...) producer method, referencing entityManagerFactory in it instead. It's odd that this even worked with the earlier version since @PersistenceContext "Expresses a dependency on a container-managed EntityManager..." which the new WELD barked about since the parameter was an EntityManagerFactory.
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() ;
}
}
回答2:
You could try using/adding few annotations to your Entity Manager that might resolve the issue.Have you tried this:@Produces
This may work with eap 7.1
@Dependent
@PersistenceContext
private EntityManager entityManager;
来源:https://stackoverflow.com/questions/51756761/jboss-eap-7-1-spring-data-jpa-cdi-extension