简体   繁体   中英

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. 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 . There is also an Entity Factory from which 'begin' all the associations to the other Entities. 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)

2) Even if the remove in the Set succeeds, the record in the database is not deleted.

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 :

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. In this case, it will only remove the link to p and cause a NOT NULL constraint violation. You need to explicitly delete() the Child.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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