我有一个@Embeddable
类,它使用属性访问来包装另一个不能由 JPA 通过字段访问直接映射的对象。它看起来像这样:
@Embeddable
@Access(AccessType.PROPERTY)
public class MyWrapper {
@NotNull
@Transient
private WrappedType wrappedField;
protected MyWrapper() {
}
public MyWrapper(WrappedType wrappedField) {
this.wrappedField = wrappedField;
}
@Transient
public WrappedType getWrappedField() {
return wrappedField;
}
public void setWrappedField(WrappedType wrappedField) {
this.wrappedField = wrappedField;
}
@Column(name = "wrappedTypeColumn")
protected String getJPARepresentation() {
return wrappedField.toString();
}
protected void setJPARepresentation(String jpaRepresentation) {
wrappedField = new WrappedType(jpaRepresentation);
}
}
坚持@Entity
一个MyWrapper
字段工作正常。但是当我执行查询以从数据库加载实体时,我得到一个NullPointerException
. 堆栈跟踪和一些调试显示 EclipselinkMyWrapper
通过调用其默认构造函数创建一个新实例,然后调用该setJPARepresentation()
方法(如预期的那样)。
但是现在意外发生了:堆栈跟踪显示getJPARepresentation()
从 setter 内部调用了,这当然会导致执行NullPointerException
时返回wrappedField.toString()
。
java.lang.NullPointerException
at MyWrapper.getJPARepresentation(MyWrapper.java:27)
at MyWrapper.setJPARepresentation(MyWrapper.java)
... 109 more
事实是,代码中显然没有对 getter 的调用,并且堆栈跟踪显示没有行号指示从 setter 中调用 getter 的位置。所以我的结论是,Eclipselink 的字节码编织器生成了对 getter 的调用。
构建解决方法很容易,但我的问题是:为什么 Eclipselink 会这样做?
PS:我在 GlassFish Server Open Source Edition 3.1.2(build 23)中使用 EclipseLink 2.3.2.v20111125-r10461