JPA EclipseLink Weaver在其setter内生成对porperty getter的调用->;空指针异常

JPA EclipseLink Weaver在其setter内生成对porperty getter的调用->;空指针异常,jpa,orm,glassfish,eclipselink,embeddable,Jpa,Orm,Glassfish,Eclipselink,Embeddable,我有一个@embeddeble类,它使用属性访问来包装另一个对象,而JPA不能通过字段访问直接映射该对象。看起来是这样的: @Embeddable @Access(AccessType.PROPERTY) public class MyWrapper { @NotNull @Transient private WrappedType wrappedField; protected MyWrapper() { } public MyWrappe

我有一个
@embeddeble
类,它使用属性访问来包装另一个对象,而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);
    }
}
MyWrapper
字段持久化
@实体
,效果很好。但是,当我执行查询以从数据库加载实体时,会得到一个
NullPointerException
。stacktrace和一些调试显示Eclipselink通过调用默认构造函数创建了一个新的
MyWrapper
实例,然后调用
setJPARepresentation()
方法(如预期的那样)

但是现在发生了意外情况:stacktrace显示从setter内部调用
getJPARepresentation()
,这当然会在执行return
wrappedField.toString()
时导致
NullPointerException

java.lang.NullPointerException
    at MyWrapper.getJPARepresentation(MyWrapper.java:27)
    at MyWrapper.setJPARepresentation(MyWrapper.java)
    ... 109 more
事实上,代码中显然没有对getter的调用,stacktrace也没有显示行号来指示getter在setter中的位置。所以我的结论是,Eclipselink的字节码编织者生成了对getter的调用

建立一个变通方法很容易,但我的问题是:Eclipselink为什么要这样做?

注意:我在GlassFish服务器开源版本3.1.2(build 23)中使用EclipseLink 2.3.2.v20111125-r10461

当启用编织(GlassFish上的默认设置)时,EclipseLink会将代码编织到属性get/set方法中

  • 变更跟踪
  • 获取组(部分对象)
  • 懒惰(关系)
对于更改跟踪支持,将编织set方法来检查新值是否与旧值不同,因此它必须调用get方法来获取旧值

现在这仍然很奇怪,因为您正在构建一个新对象,所以我不希望设置更改侦听器,也不希望绕过更改跟踪检查。您可以对代码进行反编译,以准确查看生成的内容


最简单的修复方法是在get方法中加入一个空检查,这对于代码来说可能是最好的。您还可以切换到字段访问,这在get/set方法中不会有副作用问题。您还可以使用转换器来处理转换,而不是在get/set方法中进行转换。

不能使用字段访问,因为JPA对map
MyWrapper
没有本机支持,而且我不能使用转换器。我不允许使用依赖于提供程序的机制,因为代码也必须与OpenJPA一起运行。