删除与Hibernate的OneToMany关联上的记录

时间:2014-04-25 08:42:43

标签: java database hibernate jpa

我正在使用Hibernate处理应用程序,我想删除数据库中的一些记录。相关实体是:

@Entity
public class Product {

    private String serialNumber;
    private Set<Part> parts = new HashSet<Part>();

    @Id
    public String getSerialNumber() { return serialNumber; }
    void setSerialNumber(String sn) { serialNumber = sn; }

    @OneToMany
    public Set<Part> getParts() { return parts; }
    void setParts(Set parts) { this.parts = parts; }

    ...
}


@Entity
public class Part implements Serializable {

    @Id
    @GeneratedValue
    private Long part_id;

    private String userCode = "";

       //getters and setters
       ....


}

我让Eclipse基于Entity Partpart_iduserCode中实现equals和hashCode。还有一个Entity Factory,从中“开始”与其他实体的所有关联。因此,为了保存所有更改,只需执行命令:

session.update(factory);

除了从部件中删除外,所有更改都已成功保存。我这样做:

products.getParts.remove(part);

问题的解决方案是:

1)在某些情况下part Set part未被删除,但与Set equals true的{​​{1}}进行比较part Set }返回(remove根据等于Set,但不会被删除)

2)即使{{1}}中的{{1}}成功,也不会删除数据库中的记录。

基于上述确定,在这种情况下使用不加载查询来删除记录的最佳方法是什么?

2 个答案:

答案 0 :(得分:1)

您需要明确删除子项:

session.delete(part);

来自Hibernate Docs

  

以下代码:

Parent p = (Parent) session.load(Parent.class, pid);
Child c = (Child) p.getChildren().iterator().next();
p.getChildren().remove(c);
c.setParent(null);
session.flush();
     

不会从数据库中删除c。在这种情况下,它只会删除   到p的链接并导致NOT NULL约束违规。你需要   明确删除()孩子。

Parent p = (Parent) session.load(Parent.class, pid);
Child c = (Child) p.getChildren().iterator().next();
p.getChildren().remove(c);
session.delete(c);
session.flush();

答案 1 :(得分:0)

使用hibernate映射关系时,您必须了解两个主要问题:

  • 这段关系的所有者是哪个?所有者是关系的一方,其更改将保留在数据库中。在您的情况下,所有者是Part对象。
  • 是真正的父母/子女关系还是仅仅是作文关系?在你的情况下,我认为答案是作文

如果您想使用该集管理关系,您有两个选择:

  • 使用@ElementCollection而不是@OnetoMany
  • 更改所有权。像这样:

    @OneToMany
    @JoinColumn(name="part_id")
    public Set<Part> getParts() { return parts; }
    void setParts(Set parts) { this.parts = parts; }
    

但是,不建议使用第二个选项here。见2.2.5.3.1.2节。