Hibernate有时会在子实体中留下空的外键字段

时间:2015-08-11 13:53:31

标签: java postgresql hibernate jpa spring-data-jpa

最近我的Hibernate / Postgres数据遇到了一个奇怪的现象。在未知条件下,Hibernate会创建子实体的孤立(null外键字段到父级)。但我已将@OneToMany关系注释为orphanRemoval。

“主要”实体:

@Entity
@Audited
public class Product {
    @NotNull(groups = { CheckId.class })
    @NotBlank(groups = { CheckId.class })
    @Id
    @Column(length = 32)
    private String id = IdGenerator.createId();

    @Version
    private Integer version;

    @OneToMany(fetch=FetchType.LAZY, cascade=CascadeType.ALL, orphanRemoval=true)
    @JoinColumn(name=Product.PRODUCT_ID)
    @Index(name="idx_prod_ident")
    private Set<Identifier> identifiers;

    ...
}

一个子实体:

@Entity
@Audited
public class Identifier  {

    @NotNull(groups = { CheckId.class })
    @NotBlank(groups = { CheckId.class })
    @Id
    @Column(length = 32)
    private String id = IdGenerator.createId();

    @Version
    private Integer version;

    @NotNull
    @Column(nullable=false, length=3)
    @Index(name = "idx_id_prod_type")
    private String type;

    @NotNull
    @Column(nullable=false, length=65)
    @Index(name = "idx_id_prod_value")
    private String value;

    ...
}

在Product中有很多这样的@OneToMany关系与不同(但结构相似)的实体。数百万条记录都是正确编写的,但在大多数记录中我偶尔会遇到数百条带有product_id null的记录。这怎么可能?

不幸的是,我无法轻易确定何时发生这种情况(由于缺少product_id)。此外,product_id不是子实体的Envers历史记录表的一部分。所以我无法检查产品是否仍然存在,以及最近服务对它做了什么。

有关信息:从父项中删除子实体时,可通过

完成
product.getIdentifiers.remove(identifier);

or

product.getIdentifiers.removeAll(identifiers);

or

product.getIdentifiers.clear();

这有望成为删除它们的有效方法;)

1 个答案:

答案 0 :(得分:0)

如果我正确理解您使用FetchType.LAZY - 这意味着只会在会话期间检索数据,您可以使用Hibernate.initialize检索@OneToMany字段或使用FetchType.EAGER而不是FetchType.LAZY