简体   繁体   English

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

[英]Delete a record on an OneToMany association with Hibernate

I am working on an application using Hibernate and I want to delete some records in the database. 我正在使用Hibernate应用程序,我想删除数据库中的某些记录。 The relevant Entities are: 相关实体是:

@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
       ....


}

I have let Eclipse implement equals and hashCode in Entity Part based on part_id and userCode . 我已经让Eclipse基于part_iduserCodeEntity Part实现了equals和hashCode。 There is also an Entity Factory from which 'begin' all the associations to the other Entities. 还有一个Entity Factory ,所有关联都从该Entity Factory “开始”到其他实体。 Therefore, in order to save all the changes it only necessary to execute the comand: 因此,为了保存所有更改,只需执行命令即可:

session.update(factory);

All the changes are saved successfully except from the delete from parts. 除从零件中删除外,所有更改均已成功保存。 I do: 我做:

products.getParts.remove(part);

The issues comig out are: 出现的问题是:

1) In some cases is part from the Set not removed although the comparison to a part in the Set with equals true returns (the part is in Set according to equals but it is not removed) 1)在某些情况下是partSet不除去虽然相比于partSetequals true返回(该part是在Set根据等号,但它不被除去)

2) Even if the remove in the Set succeeds, the record in the database is not deleted. 2)即使Setremove成功完成,数据库中的记录也不会被删除。

Based on the above ascertainments what is the best way to remove the records in this case using not loads of queries? 根据上述确定,在这种情况下不使用查询来删除记录的最佳方法是什么?

You need to explicitly remove the child: 您需要明确删除子项:

session.delete(part);

From Hibernate Docs : Hibernate Docs中

The following code: 如下代码:

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

will not remove c from the database. 不会从数据库中删除c。 In this case, it will only remove the link to p and cause a NOT NULL constraint violation. 在这种情况下,它将仅删除到p的链接,并导致违反NOT NULL约束。 You need to explicitly delete() the Child. 您需要显式delete()子级。

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

When using hibernate to map relationships you must be aware of two main concerns: 使用休眠模式映射关系时,必须注意两个主要问题:

  • Which is the owner of the relationship? 关系的所有者是谁? The owner is the side of the relation whose changes will be persisted in database. 所有者是关系的一方,其更改将保留在数据库中。 In your case the owner is the Part object. 在您的情况下,所有者是Part对象。
  • Is a true parent/child relationship or simply a composition relationship? 是真正的父母/子女关系,还是仅仅是构成关系? In your case I think the answer is composition 在您的情况下,我认为答案是构图

If you want to manage the relation using the set, you have two options: 如果要使用集合管理关系,则有两个选择:

  • use @ElementCollection instead of @OnetoMany 使用@ElementCollection而不是@OnetoMany
  • change ownership. 更改所有权。 Something like this: 像这样:

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

However, the second option is not recommended here . 但是, 此处不建议第二种选择。 See section 2.2.5.3.1.2. 参见第2.2.5.3.1.2节。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM