我在EclipseLink中生成静态元模型类时遇到问题。 在我的项目中,我首先使用以下方法为我的实体生成静态元模型:
1) org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor和IntelliJ IDEA 此类已生成为: target / generated-sources
然后我尝试在EclipseLink(GlassFish embedded)中使用这样的Hibernate生成的元模型类(例如下面),但是包含对metamodel属性的引用的代码行抛出 NullPointerException 异常:
SingularAttribute<Employee, String> descriptionAttr = Employee_.description;
predicates.add(criteriaBuilder.like(employee.get(descriptionAttr), "%" + description + "%"));
此处,emploee.get(&gt;&gt; null&lt;&lt;)抛出异常。
@Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor")
@StaticMetamodel(Employee.class)
public abstract class Employee_ extends pl.salonea.entities.NaturalPerson_ {
public static volatile SetAttribute<Employee, Skill> skills;
public static volatile SetAttribute<Employee, ProviderService> suppliedServices;
public static volatile SetAttribute<Employee, EmployeeRating> receivedRatings;
public static volatile SingularAttribute<Employee, String> description;
public static volatile SetAttribute<Employee, Education> educations;
public static volatile SingularAttribute<Employee, String> jobPosition;
public static volatile SetAttribute<Employee, TermEmployeeWorkOn> termsOnWorkStation;
}
2)接下来我认为这个元模型类可能是特定于实现的。所以我使用EclipseLink类似地生成它们 org.eclipse.persistence.internal.jpa.modelgen.CanonicalModelProcessor 和 target / generated-sources-eclipselink (如图所示)
最后,我有一个像metamodel这样的目录stracture:
3)我也在 build.gradle 这样的配置中使用,因为我认为在项目中包含这些生成的源:
if(hasProperty('jboss')) {
sourceSets {
main {
java {
srcDir 'target/generated-sources/'
}
}
}
} else {
sourceSets {
main {
java {
srcDir 'target/generated-sources-eclipselink/'
}
}
}
}
这样我想使用Hibernate生成的类与Jboss和EclipseLink生成的类与EclipseLink。
4)这样的配置只有在WilfFly / Hibernate上运行才有效,但在GlassFish / EclipseLink上没有这个 NullPointerException
5)在 persistence.xml 中,我有更多的EclipseLink生成使用这个属性用于一个持久性单元
<property name="eclipselink.canonicalmodel.subpackage" value="metamodel" />
和第二个持久性单元的这种属性(以避免重复冲突)
<property name="eclipselink.canonicalmodel.subpackage" value="metamodel_local" />
但我试图不使用这一代。它位于子包中,在我的代码中我只导入以前生成的元模型类。 原因是我想在Hibernate / Eclipse生成的同一命名空间元模型类中使用它们并适当地使用它们。 但是,如果Hibernate生成的元模型类也可以与EclipseLink一起使用,那么仅使用一代就不会有问题。
6)此外,我不能使用EclipseLink persistence.xml 属性生成的元模型类,因为每次运行/构建项目时它们都会重新生成。我需要在我的代码中手动修改两个元模型类,因为它们是从单个抽象元模型类继承而来的。在这里,我将重写在metamodel类的SetAttribute上的具有ConcreteType的子类AbstractType。
7)最后,我在使用元模型类配置运行集成测试时得到的错误
Caused by: java.lang.NullPointerException
at org.eclipse.persistence.internal.jpa.querydef.FromImpl.get(FromImpl.java:263)
at pl.salonea.ejb.stateless.EmployeeFacade.findByMultipleCriteria(EmployeeFacade.java:295)
at pl.salonea.ejb.stateless.EmployeeFacade.findByMultipleCriteria(EmployeeFacade.java:269)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1081)
at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1153)
at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:4786)
at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:656)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822)
at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608)
at org.jboss.weld.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:46)
at org.jboss.weld.ejb.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:52)
at sun.reflect.GeneratedMethodAccessor113.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:883)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822)
at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608)
at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doCall(SystemInterceptorProxy.java:163)
at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:140)
at sun.reflect.GeneratedMethodAccessor141.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:883)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822)
at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:369)
at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:4758)
at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:4746)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:212)
... 149 more
答案 0 :(得分:2)
- 我正在检查EclipseLink来源:
public <Y> Path<Y> get(SingularAttribute<? super X, Y> att){
if (att.getPersistentAttributeType().equals(
PersistentAttributeType.BASIC)) {
return new PathImpl<Y>(
this, this.metamodel, att.getBindableJavaType(),
this.currentNode.get(att.getName()), att);
} else {
Class<Y> clazz = att.getBindableJavaType();
Join join = new JoinImpl<X, Y>(
this, this.metamodel.managedType(clazz),
this.metamodel, clazz,
this.currentNode.get(att.getName()), att);
this.joins.add(join);
return join;
}
}
FromImpl.java:263是 if 语句的条件,因此看起来att.getPersistentAttributeType()
返回null
。
如果您在https://bugs.eclipse.org/bugs/enter_bug.cgi?product=EclipseLink上提交针对EclipseLink的错误,那将是件好事 组件是JPA。请将此描述复制粘贴并提供一些测试用例(使用此元模型的示例应用程序),让我们重现它并开发一些修复。
答案 1 :(得分:0)
即使使用2.7.4
,我仍然面临着这个问题。
我真的很好奇AttributeProxyImpl.java
中的以下方法。
public synchronized Attribute<X, T> getAttribute(){
if (attribute == null){
for (WeakReference<EntityManagerFactoryImpl> factoryRef: factories){
EntityManagerFactoryImpl factory = factoryRef.get();
if (factory != null){
factory.getDatabaseSession();
} else {
factories.remove(factoryRef);
}
}
}
return attribute;
}
设置attribute
字段的位置在哪里?
答案 2 :(得分:0)
问题可能出在初始化规范元模型失败。 您可以调查您的eclipselink日志以检查类似的内容:
mask1 = (m.ne(m.shift()).cumsum()[m]).value_counts().eq(3)
print (mask1)
3 False
1 False
dtype: bool
if mask1.any():
print ('Butter and Jam missing in 3 consecutive rows')
else:
print ('Butter and Jam are NOT missing in 3 consecutive rows')
就我而言,修复初始化后,NPE消失了。
答案 3 :(得分:-2)
我知道这是一张旧票,但我仍然想让你们知道我们如何解决这个问题。特别是最后一个nullpointer异常。
问题是,当您第一次使用Criteriabuilder时,您的entitimanager未加载。 要解决此问题,您可以在persistence.xml中设置以下内容
<property name="eclipselink.deploy-on-startup" value="true" />