获取延迟加载的@ManyToOne实体的@Id将返回null

时间:2015-01-29 11:47:39

标签: java hibernate jpa lazy-loading

我正在使用Hibernate 4.3.8.Final并且在检索lazy fetched属性的@Id属性时遇到问题:对于调用aidConfiguration.getChipApplication().getId()的附加类,allways返回null。其他属性,例如。 aidConfiguration.getChipApplication().getVersion()正确返回DB中的值。如果chipApplication未延迟加载(请参阅代码中的注释),则aidConfiguration.getChipApplication().getId()将返回正确的非空值。

我错了什么?

顺便说一句,我需要它来偷懒。

BaseEntity:

@MappedSuperclass
public class BaseEntity implements Serializable {

    @Id
    @Column(name = "ID", unique = true)
    @Size(min = 1, max = 255)
    private String id;

    @PrePersist
    public final void generateUuid() {
        if (this.getId() == null) {
            this.setId(UUID.randomUUID().toString());
        }
    }

    public final String getId() {
        return id;
    }

    public final void setId(final String id) {
        this.id = id;
    }
}

AidConfiguration:

@Entity
@Audited
public class AidConfiguration extends BaseEntity {

    @Column
    @NotBlank
    private String name;

    @NotNull
    @ManyToOne(fetch = FetchType.LAZY) // if it is EAGER (defaut) then then aidConfiguration.getChipApplication().getId() returns correctly non-null value
    private ChipApplication chipApplication;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "aidConfiguration", cascade = CascadeType.ALL) // cascade for auto-saving and deleting items
    private List<AidConfigurationItem> aidConfigurationItems;

    public String getName() {
        return name;
    }

    public void setName(final String name) {
        this.name = name;
    }

    public ChipApplication getChipApplication() {
        return chipApplication;
    }

    public void setChipApplication(final ChipApplication chipApplication) {
        this.chipApplication = chipApplication;
    }

    public List<AidConfigurationItem> getAidConfigurationItems() {
        return aidConfigurationItems;
    }

    public void setAidConfigurationItems(final List<AidConfigurationItem> aidConfigurationItems) {
        this.aidConfigurationItems = aidConfigurationItems;
    }
}

ChipApplication:

@Entity
@Audited
public class ChipApplication extends BaseEntity {

    @Column
    @NotBlank(message = "Aid can not be empty")
    private String aid;

    @Column
    @NotBlank(message = "Product can not be empty")
    private String product;

    @Column
    @NotBlank(message = "Version can not be empty")
    private String version;

    @NotNull(message = "Network is mandatory")
    @ManyToOne(fetch = FetchType.LAZY)
    private Network network;

    @ManyToMany(fetch =  FetchType.EAGER)
    private List<AidTag> aidTags;

    public String getAid() {
        return aid;
    }

    public void setAid(final String aid) {
        this.aid = aid;
    }

    public String getProduct() {
        return product;
    }

    public void setProduct(final String product) {
        this.product = product;
    }

    public String getVersion() {
        return version;
    }

    public void setVersion(final String version) {
        this.version = version;
    }

    public Network getNetwork() {
        return network;
    }

    public void setNetwork(final Network network) {
        this.network = network;
    }

    public List<AidTag> getAidTags() {
        return aidTags;
    }

    public void setAidTags(final List<AidTag> aidTags) {
        this.aidTags = aidTags;
    }
}

2 个答案:

答案 0 :(得分:1)

迟到了,但问题HH-9588仍然没有得到解决,我只是遇到了同样的问题(XML映射而不是注释)。

当绑定是懒惰时,无法从getter获取id。渴望或获取加入时得到它。

通过摆脱&#34; final&#34;来解决这个问题。 getId()访问器上的修饰符。 (最后这里是为了保护所有实体在超类中定义主键/标识符的方式)

之前:

public abstract class Foo  {

Long id;

public final Long getId() {
    return id;
}

protected final void setId( Long id ){
    this.id = id;
}
...

之后:

public abstract class Foo {

Long id;

// No more final 
public Long getId() {
    return id;
}

// No more final 
protected void setId( Long id ){
    this.id = id;
}
...

现在,我也可以使用惰性绑定获取Id。

对我来说,这是&#34; final&#34;修饰符不允许Hibernate按预期代理此访问器。其他访问者不是&#34; final&#34;,可以从代理访问其值。

所以,我想知道HH-9588是真的是一个错误还是对hibernate方式的误解?

答案 1 :(得分:0)

这似乎是一个错误,如果你不错过任何东西。我会在Hibernate的bug跟踪系统上报告它。如果您之后使用指向该错误的链接更新此答案,那将是很好的。