如何在非 EJB @Dependent 子类中获取 CDI 生成的实体管理器,抛出 NPE?
How to get CDI produced entitymanager in non EJB @Dependent subclass, throwing NPE?
持久性 API 使用在 persistence.xml
中配置的 JTA 管理事务。
EntitymanagerProducer.java
@PersistenceContext( unitName = "PRO" )
EntityManager proEm;
@pro
@Produces
public EntityManager createProEntityManager () {
return this.proEm;
}
上面生成的 EntityManager
可以被注入到任何 @Stateless
带有限定符 @Pro
的 bean 中,如下所示,
@Stateless
@Local( OutRepositoryBeanLocal.class )
@Remote( OutRepositoryRemote.class )
@LocalBean
@TransactionAttribute( TransactionAttributeType.MANDATORY )
public class OutRepositoryBean implements OutRepositoryBeanLocal, OutRepositoryRemote {
@Inject
@Pro
private EntityManager entityManager;
@Inject
OutRepository outRepository;
/**
*
*/
@PostConstruct
private void init () {
this.outRepository.setEntityManager( this.entityManager );
}
上面这段代码可以正常运行,没有错误。但是在将工作委托给 @Dependent
subclasses 问题时,
OutRepository.java
@Dependent
public class OutRepository extends BaseService< Out, Long > {
public OutRepository() {
// TODO Auto-generated constructor stub
}
@Override
protected Class< Out > t () {
return Out.class;
}
public List< Out > getOuts ( Long proId, String Out) {
CriteriaBuilder builder = this.entityManager.getCriteriaBuilder(); <= NPE
CriteriaQuery< Out > criteriaQuery = builder.createQuery( t() );
Root< Out > endPointConfig = criteriaQuery.from( t() );
criteriaQuery.select( endPoint );
TypedQuery< Out > query = this.entityManager.createQuery( criteriaQuery );
return query.getResultList();
}
而 BaseService.java
是包含通用 crud 方法的 abstract
class。
BaseService.java
@Dependent
public abstract class BaseService< T, I extends Serializable > implements BaseEntity< T, I > {
protected abstract Class< T > t ();
@PostConstruct
protected abstract void init ();
public PersistenceUnitUtil persistenceUnitUtil;
public EntityManager entityManager;
@TransactionAttribute( TransactionAttributeType.MANDATORY )
@Override
public T save ( T t ) {
this.entityManager.persist( t );
return t;
}
虽然调用了 outRepsitory.save()
,但交易没有问题,一切正常。然而 outRepository.getOuts(Long proId,String Out)
,发生以下异常
[2/7/18 18:19:36:187 IST] 0000003d BusinessExcep E CNTR0020E: EJB threw an unexpected (non-declared) exception during invocation of method "getOuts" on bean "BeanId(pro-ear#pro-web-0.0.1-SNAPSHOT.war#OutRepositoryBean, null)". Exception data: java.lang.NullPointerException
at org.apache.openjpa.persistence.meta.MetamodelImpl.populate(MetamodelImpl.java:321)
at org.apache.openjpa.persistence.meta.MetamodelImpl.instantiate(MetamodelImpl.java:255)
at org.apache.openjpa.persistence.meta.MetamodelImpl.find(MetamodelImpl.java:224)
at org.apache.openjpa.persistence.meta.MetamodelImpl.<init>(MetamodelImpl.java:89)
at org.apache.openjpa.persistence.EntityManagerFactoryImpl.getMetamodel(EntityManagerFactoryImpl.java:346)
at org.apache.openjpa.persistence.EntityManagerFactoryImpl.getCriteriaBuilder(EntityManagerFactoryImpl.java:333)
at org.apache.openjpa.persistence.EntityManagerImpl.getCriteriaBuilder(EntityManagerImpl.java:1649)
at org.apache.openjpa.persistence.EntityManagerImpl.getCriteriaBuilder(EntityManagerImpl.java:101)
at com.ibm.ws.jpa.management.JPAExEmInvocation.getCriteriaBuilder(JPAExEmInvocation.java:394)
at com.ibm.ws.jpa.management.JPAEntityManager.getCriteriaBuilder(JPAEntityManager.java:494)
at com.org.uck.pro.db.out.control.OutRepository.getOuts(OutRepository.java:68)
at com.org.uck.pro.db.out.control.OutRepositoryBean.getOuts(OutRepositoryBean.java:108)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at com.ibm.ejs.container.EJSContainer.invokeProceed(EJSContainer.java:6207)
at com.ibm.ejs.container.interceptors.InvocationContextImpl.proceed(InvocationContextImpl.java:568)
at org.apache.webbeans.ejb.common.interceptor.OpenWebBeansEjbInterceptor.callInterceptorsAndDecorators(OpenWebBeansEjbInterceptor.java:528)
at org.apache.webbeans.ejb.common.interceptor.OpenWebBeansEjbInterceptor.callToOwbInterceptors(OpenWebBeansEjbInterceptor.java:200)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at com.ibm.ejs.container.interceptors.InterceptorProxy.invokeInterceptor(InterceptorProxy.java:227)
at com.ibm.ejs.container.interceptors.InvocationContextImpl.proceed(InvocationContextImpl.java:548)
at org.apache.webbeans.ejb.WSEJBInterceptor.callToOwbInterceptors(WSEJBInterceptor.java:152)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at com.ibm.ejs.container.interceptors.InterceptorProxy.invokeInterceptor(InterceptorProxy.java:227)
at com.ibm.ejs.container.interceptors.InvocationContextImpl.proceed(InvocationContextImpl.java:548)
at com.ibm.ejs.container.interceptors.InvocationContextImpl.doAroundInvoke(InvocationContextImpl.java:229)
at com.ibm.ejs.container.EJSContainer.invoke(EJSContainer.java:6098)
at com.org.uck.pro.db.out.boundary.EJSLocal1SLOutRepositoryBean_03076fb6.getOuts(EJSLocal1SLOutRepositoryBean_03076fb6.java)
at com.org.uck.pro.ejb.outs.control.OutBean.getOuts(OutBean.java:109)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
NullPointerException
在 CriteriaBuilder builder = this.entityManager.getCriteriaBuilder();
上,尝试使用 super.entitymanger
调用 entitymanager
仍然存在相同的错误。
--
谢谢。
BaseService中没有Inject注解
应该像你在 OutRepositoryBean 中完成的那样
@Inject @Pro
public EntityManager entityManager;
持久性 API 使用在 persistence.xml
中配置的 JTA 管理事务。
EntitymanagerProducer.java
@PersistenceContext( unitName = "PRO" )
EntityManager proEm;
@pro
@Produces
public EntityManager createProEntityManager () {
return this.proEm;
}
上面生成的 EntityManager
可以被注入到任何 @Stateless
带有限定符 @Pro
的 bean 中,如下所示,
@Stateless
@Local( OutRepositoryBeanLocal.class )
@Remote( OutRepositoryRemote.class )
@LocalBean
@TransactionAttribute( TransactionAttributeType.MANDATORY )
public class OutRepositoryBean implements OutRepositoryBeanLocal, OutRepositoryRemote {
@Inject
@Pro
private EntityManager entityManager;
@Inject
OutRepository outRepository;
/**
*
*/
@PostConstruct
private void init () {
this.outRepository.setEntityManager( this.entityManager );
}
上面这段代码可以正常运行,没有错误。但是在将工作委托给 @Dependent
subclasses 问题时,
OutRepository.java
@Dependent
public class OutRepository extends BaseService< Out, Long > {
public OutRepository() {
// TODO Auto-generated constructor stub
}
@Override
protected Class< Out > t () {
return Out.class;
}
public List< Out > getOuts ( Long proId, String Out) {
CriteriaBuilder builder = this.entityManager.getCriteriaBuilder(); <= NPE
CriteriaQuery< Out > criteriaQuery = builder.createQuery( t() );
Root< Out > endPointConfig = criteriaQuery.from( t() );
criteriaQuery.select( endPoint );
TypedQuery< Out > query = this.entityManager.createQuery( criteriaQuery );
return query.getResultList();
}
而 BaseService.java
是包含通用 crud 方法的 abstract
class。
BaseService.java
@Dependent
public abstract class BaseService< T, I extends Serializable > implements BaseEntity< T, I > {
protected abstract Class< T > t ();
@PostConstruct
protected abstract void init ();
public PersistenceUnitUtil persistenceUnitUtil;
public EntityManager entityManager;
@TransactionAttribute( TransactionAttributeType.MANDATORY )
@Override
public T save ( T t ) {
this.entityManager.persist( t );
return t;
}
虽然调用了 outRepsitory.save()
,但交易没有问题,一切正常。然而 outRepository.getOuts(Long proId,String Out)
,发生以下异常
[2/7/18 18:19:36:187 IST] 0000003d BusinessExcep E CNTR0020E: EJB threw an unexpected (non-declared) exception during invocation of method "getOuts" on bean "BeanId(pro-ear#pro-web-0.0.1-SNAPSHOT.war#OutRepositoryBean, null)". Exception data: java.lang.NullPointerException
at org.apache.openjpa.persistence.meta.MetamodelImpl.populate(MetamodelImpl.java:321)
at org.apache.openjpa.persistence.meta.MetamodelImpl.instantiate(MetamodelImpl.java:255)
at org.apache.openjpa.persistence.meta.MetamodelImpl.find(MetamodelImpl.java:224)
at org.apache.openjpa.persistence.meta.MetamodelImpl.<init>(MetamodelImpl.java:89)
at org.apache.openjpa.persistence.EntityManagerFactoryImpl.getMetamodel(EntityManagerFactoryImpl.java:346)
at org.apache.openjpa.persistence.EntityManagerFactoryImpl.getCriteriaBuilder(EntityManagerFactoryImpl.java:333)
at org.apache.openjpa.persistence.EntityManagerImpl.getCriteriaBuilder(EntityManagerImpl.java:1649)
at org.apache.openjpa.persistence.EntityManagerImpl.getCriteriaBuilder(EntityManagerImpl.java:101)
at com.ibm.ws.jpa.management.JPAExEmInvocation.getCriteriaBuilder(JPAExEmInvocation.java:394)
at com.ibm.ws.jpa.management.JPAEntityManager.getCriteriaBuilder(JPAEntityManager.java:494)
at com.org.uck.pro.db.out.control.OutRepository.getOuts(OutRepository.java:68)
at com.org.uck.pro.db.out.control.OutRepositoryBean.getOuts(OutRepositoryBean.java:108)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at com.ibm.ejs.container.EJSContainer.invokeProceed(EJSContainer.java:6207)
at com.ibm.ejs.container.interceptors.InvocationContextImpl.proceed(InvocationContextImpl.java:568)
at org.apache.webbeans.ejb.common.interceptor.OpenWebBeansEjbInterceptor.callInterceptorsAndDecorators(OpenWebBeansEjbInterceptor.java:528)
at org.apache.webbeans.ejb.common.interceptor.OpenWebBeansEjbInterceptor.callToOwbInterceptors(OpenWebBeansEjbInterceptor.java:200)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at com.ibm.ejs.container.interceptors.InterceptorProxy.invokeInterceptor(InterceptorProxy.java:227)
at com.ibm.ejs.container.interceptors.InvocationContextImpl.proceed(InvocationContextImpl.java:548)
at org.apache.webbeans.ejb.WSEJBInterceptor.callToOwbInterceptors(WSEJBInterceptor.java:152)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at com.ibm.ejs.container.interceptors.InterceptorProxy.invokeInterceptor(InterceptorProxy.java:227)
at com.ibm.ejs.container.interceptors.InvocationContextImpl.proceed(InvocationContextImpl.java:548)
at com.ibm.ejs.container.interceptors.InvocationContextImpl.doAroundInvoke(InvocationContextImpl.java:229)
at com.ibm.ejs.container.EJSContainer.invoke(EJSContainer.java:6098)
at com.org.uck.pro.db.out.boundary.EJSLocal1SLOutRepositoryBean_03076fb6.getOuts(EJSLocal1SLOutRepositoryBean_03076fb6.java)
at com.org.uck.pro.ejb.outs.control.OutBean.getOuts(OutBean.java:109)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
NullPointerException
在 CriteriaBuilder builder = this.entityManager.getCriteriaBuilder();
上,尝试使用 super.entitymanger
调用 entitymanager
仍然存在相同的错误。
-- 谢谢。
BaseService中没有Inject注解
应该像你在 OutRepositoryBean 中完成的那样
@Inject @Pro
public EntityManager entityManager;