Arian
Arian

Reputation: 7719

Hibernate: Delete an entity in network of entities

In my Spring boot app, there are two types of entities: User and Group:

  1. User can own 0 to N groups
  2. Group can have 1 to M members

In the User class there is a list of Group that he/she owns or is a member of, and in the Group class, there is a list of User (i.e. members).

These classes refer to each other using hibernate annotations.

class User {
    @ManyToMany(cascade = CascadeType.REFRESH)
    private List<Group> groups;
}

class Group {
    @ManyToOne(cascade = CascadeType.REFRESH)
    @NotNull
    @JoinColumn(name="OWNER_ID", referencedColumnName="id")
    private User owner;

    @ManyToMany
    @JoinTable(joinColumns = @JoinColumn(referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(referencedColumnName = "id"))
    private List<User> members;
}

In the User service layer there's a Delete method which is supposed to delete a user from the repository. This delete should fire a series of actions: all the groups owned by that user gets deleted, and the deleted groups should be removed from list of groups of their members. All these should be saved to the repository.

If I add other types of entities to this network, this process gets much more complicated.

My question is: Doesn't hibernate handle this automatically ? Should I grab each member and delete the group one by one and save it to the repository ?

Upvotes: 0

Views: 132

Answers (1)

Yogi
Yogi

Reputation: 1895

CascadeType.REFRESH means Managed objects can be reloaded from the database by using the refresh method.

This will not help you solving your requirement. You need to use “orphanRemoval = true” CascadeType. “orphanRemoval = true” removes an owned object from the database when it’s removed from its owning relationship.

Example:

EmployeeEntity.java

@Entity @Table(name = "Employee")
public class EmployeeEntity implements Serializable
{
    private static final long serialVersionUID = -1798070786993154676L;
    @Id @Column(name = "ID", unique = true, nullable = false)
    private Integer  employeeId;

    @Column(name = "FIRST_NAME", unique = false, nullable = false, length = 100)
    private String  firstName;

    @Column(name = "LAST_NAME", unique = false, nullable = false, length = 100)
    private String lastName;

    @OneToMany(orphanRemoval = true, mappedBy = "employee")
    private Set<AccountEntity> accounts;

}

AccountEntity.java

@Entity (name = "Account") @Table(name = "Account")
public class AccountEntity implements Serializable
{
    private static final long serialVersionUID = 1L;

    @Id @Column(name = "ID", unique = true, nullable = false)
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Integer           accountId;

    @Column(name = "ACC_NO", unique = false, nullable = false, length = 100)
    private String            accountNumber;

    @ManyToOne
    private EmployeeEntity employee;
}   

OR You can use CascadeType.ALL too.

For further reading, go through below link:

CascadeTypes

Upvotes: 1

Related Questions