Hibernate @ManyToMany delete non-owner – prevent owner being deleted

The solution to deleting a child in a @ManyToMany relationship and deleting the parents in the process.

Take the following many-to-many relationship

image_thumb.png

mapped in such a way that TClass is the owning entity and TStudent is the non-owning entity.

TClass.java – @ManyToMany mapping

 

TStudent.java – @ManyToMany mapping

 

This conventional @ManyToMany has a problem when it comes to deleting a Student.

The Cascade.All results in the row being deleted from the link table but undesirably the class entry is deleted from the t_class table also.

If the CascadeType is set to be non REMOVE, i.e. CascadeType.REMOVE is absent, the result is a foreign key constraint violation. The violation is caused during an attempt by hibernate to remove the t_student entry but not the link table entry.

The solution is to map the non-owning entity as an owner also. This results in the ability to delete students without deleting classes in the process. The original ability to delete classes without deleting students remains.

Here’s the mapping:

TStudent.java – @ManyToMany mapping

Allows student deletions without deleting classes in the process.

The TClass mapping remains as it was.

 

Comments welcome…..

 

 

ote that the joinColumns and inverseJoinColumsn are exact opposites of the mapping in TClass.java

 

3 Comments

    • Hi Bilal

      Thanks for the comment.

      The situation you’re referring to is because List’s are used.
      List<TStudent> TStudents = new ArrayList<TStudent>();
      List<TClass> TClasses = new ArrayList<TClass>();

      This allows a parent to have multiple instances of the same child.
      You’re correct, this doesn’t really make much sense when it comes to students in classes because e.g. Mary cannot be in the same class twice, there is only on Mary after all.

      However, if the class TClass (as in school/course, not a Java class) was some sort of prolonged workshop spanning several days/weeks, you may want to count the number of times Mary dropped in. In this case, it would make since to allow multiple instances in the link table in order to get a count.

      The solution to your problem is to use Set’s instead of List’s.

      Set<TStudent> TStudents = new HashSet<TStudent>();
      Set<TClass> TClasses = new HashSet<TClass>();

      Set’s only allow one instance of an object to exist in them.

      This situation in general comes from the way in which Hibernate does updates on Many-to-Many configurations. During an update it removes all corresponding link table rows and re-inserts them.

      Feel free to have a look at this tutorial for further information: http://outbottle.com/java-hibernate-manytomany-tutorial-with-add-and-delete-examples/