我的关系很简单

[SampleAliasMask] has many [SampleAliasMaskPart]


我的问题是,当我使用集合部件持久保存SampleAliasMask的新实例时,遇到约束冲突,即从SampleAliasMaskPart表到SampleAliasMask的外键链接被设置为NULL。

我正在使用休眠注释进行映射,例如:

@Entity
@Table(name="SAMPLE_ALIAS_MASK")
public class SampleAliasMask extends ClientEntity {
    @OneToMany(mappedBy = "sampleAliasMask", fetch = FetchType.EAGER, cascade = javax.persistence.CascadeType.ALL, orphanRemoval = true)
    @Cascade(CascadeType.ALL)
    @Length(min = 1, message = "The sample alias mask must have components")
    private Set<SampleAliasMaskPart> components;


关系的另一半映射为:

@Entity
@Table(name="SAMPLE_ALIAS_MASK_PART")
public class SampleAliasMaskPart extends ClientEntity {
    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    @JoinColumn(name = "SAMPLE_ALIAS_MASK_ID", nullable = false)
    private SampleAliasMask sampleAliasMask;


ClientEntity的相关部分是

@MappedSuperclass
public abstract class ClientEntity {
    @Id
    @Column(name="ID")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;


我正在创建这样的部分:

HashSet<SampleAliasMaskPart> components = new HashSet<>();
for(Map<String, Object> c : this.components) {
    SampleAliasMaskPart component = new SampleAliasMaskPart(Integer.parseInt(c.get("value").toString(), 10), c.get("name").toString());
    result.validate(component);
    components.add(component);
}
mask.setComponents(components);


我得到的确切错误是:

java.sql.BatchUpdateException: ORA-01400: cannot insert NULL into ("ST"."SAMPLE_ALIAS_MASK_PART"."SAMPLE_ALIAS_MASK_ID")




我怀疑问题与以下事实有关:我从未明确设置SampleAliasMaskPart.sampleAliasMask,但为什么我需要这样做?这种关系永远不会被揭露或浏览。该字段仅用于映射目的,这使我认为我正在映射此错误。

最佳答案

您的假设是正确的。 Hibernate使用关联的拥有方来知道该关联是否存在。而拥有方是没有mappedBy属性的一方。

一般规则是,当您具有双向关联时,您有责任通过初始化/修改关联的两侧来使对象图保持一致。 Hibernate不太关心它,但是如果您不初始化拥有方,它将不会持久化关联。

请注意,您不必强制将此关联设为双向。如果不这样做,则将零件添加到蒙版就足够了,因为这一面(这是唯一面)是拥有面。

10-01 12:32