arjacsoh
arjacsoh

Reputation: 9232

Use of Cascade in ManyToOne relation

Is it appropriate to use Cascade in both sides of a ManyToOne association in Hibernate Entities? To make my question more concrete, let 's assume that someone has the following related Entities:

   public class Department
    {
    public long id;

    @OneToMany(mappedBy = "department", cascade=cascadeType.REMOVE)
    private Set<Employee> employees;
    }

    public class Employee{

    @GeneratedValue(strategy=GeneratedValue.identity)
    public longempid;

    @ManyToOne
    public Department department;
    }

In the above relation a Department has many Employees, hence it is rational to force the Employees to be deleted when a Department is deleted. Am I right?

However, the owner of the relation is the Employee. Therefore my question is, what would be the appropriate-correct choice ragarding where to put the cascadeType.PERSIST. Could I choose one of the two sides, according to special needs or could I put it on both sides as well? If I put it on the Department side, does the following code save the Employees as well, considering the Employee is the owner of the relation?

Employee e1 = new Employee();
Employee e2 = new Employee();
Department d = new Department();
d.getEmployees.add(e1);
d.getEmployees.add(e2);
em.persist(d);

I am almost sure the the opposite works if I put the cascadeType.PERSIST on the Employee side.(Saving the Employee would save the Department as well).

Upvotes: 3

Views: 2626

Answers (1)

JB Nizet
JB Nizet

Reputation: 691715

First of all, in the code you posted, the employee is not the owner of the association. It would if the association was bidirectional, and if the OneToMany association is thus defined with a mappedBy attribute:

@OneToMany(mappedBy = "department", cascade = cascadeType.REMOVE)
private Set<Employee> employees;

(note that I also made the field private. Public fields should never be used).

Regarding the removal of a department: in my company, when a department is removed, all its employees are not automatically fired. They could be assigned to another department, or even stay in the company without being affected to a department, but they're not deleted. I understand your application doesn't necessarily models the real world, but no, it is not necessarily rational to force the employees to be deleted when a department is deleted.

Now, assuming the mapping is as above, yes, you can perfectly add a PERSIST cascade to the OneToMany association. Cascades and ownership are orthogonal notions. If you want the persist() operation to be cascaded from a department to its employees (ie. if you want to create employees when creating a department), then add this cascade. For the association to be saved, since the owner side is Employee, the employee.department field will have to be correctly initialized, though.

Upvotes: 4

Related Questions