【问题标题】:Hibernate unidirectional OneToMany delete violates constraint ( optional=false at parent side?)Hibernate 单向 OneToMany 删除违反约束(在父端 optional=false?)
【发布时间】:2013-01-01 01:21:00
【问题描述】:

我使用 Hibernate 3.6,我有这样的东西:

@Entity 
public class Parent { 
    @OnyToMany( fetch = FetchType.LAZY, cascade = { ascadeType.ALL } )   
    @Cascade( { org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE )   
    @JoinColumn( name="Parent_ID" )
    public List<Child> getChildren() { return children; }   
public void setChildren( List<Child> children ) { this.children = children; }
private transient List<TitleMetadataCategory> children;
...
 }

@Entity
public class Child {
....
}

关联是单向的,有几个原因,我不想改变它。此外,孤儿不存在,因此存在 CHILD.PARENT_ID 不为空的 DB 约束。 一切正常,除了删除孩子。当我这样做时

parent.getChildren().remove(child); session.saveOrUpdate(parent)

它失败了。

因为我没有

@ManyToOne( optional=false )

在子节点,Hibernate 尝试使用 PARENT_ID=NULL 更新子节点,但由于 DB 约束而失败。

有什么办法可以解决吗?

【问题讨论】:

  • 单向休眠不允许将关联映射到没有连接的实体。
  • 它已通过映射的 DB 中的 Child.Parent_ID 列连接

标签: java hibernate jpa-2.0 hibernate-mapping


【解决方案1】:

你试过了吗

@JoinColumn(name = "Parent_ID", nullable = false)

?

另外,请注意附加的实体是自动持久化的。您无需致电saveOrUpdate()

【讨论】:

  • 我试过了,得到 org.hibernate.MappingException: Repeated column in mapping for entity PARENT_ID Exception
  • 那么这意味着您已经映射了子表中的 parentId 列。您不应该这样做,因为它已经映射为父表中的连接列。如果子级知道其父级,则使其成为双向关联。如果它不知道它,那么它不应该映射 parent_id 列。而且您确实也需要移除孤儿。
  • 是的,我很少有带有孤儿删除的双向映射,它可以工作。但是,父母有大约 15 种类型的孩子,其中一些有自己的孩子。我很害怕为每一个定义双向映射,因为我已经遇到了一些级联冲突。
【解决方案2】:

JB Nizet 的答案是有效的,但有一个更正。由于我也有 Child.getParentId() 方法(不是 getParent() ),因此它的 Column 注释除了 Parent.getChildren() 关联中的 nullable=false, updatable=false 之外,还应该有 nullable=false, insertable=false, updateble=false 参数。

【讨论】:

    【解决方案3】:

    在当前配置下,当您从 children 集合中删除 Child 时,Hibernate 不知道必须将其删除(这称为孤立删除)。您需要 @OneToMany(orphanRemoval=true) 在父级中。 org.hibernate.annotations.CascadeType.DELETE 仅指定在删除整个父级时也应删除子级。

    【讨论】:

    • 我已经尝试过了,但它不起作用,因为休眠首先安排更新操作,然后才检查它是否是孤立的并安排删除操作。结果队列中有删除操作,但更新之前抛出异常。
    • 那就和JB Nizet建议的@JoinColumn(name = "Parent_ID", nullable = false)一起试试吧
    猜你喜欢
    • 2021-05-09
    • 1970-01-01
    • 1970-01-01
    • 2014-03-17
    • 2012-07-15
    • 1970-01-01
    • 2019-01-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多