Search code examples
javahibernateannotationscascadecascading-deletes

Hibernate: One To Many Relation on cascade save but doesn't delete


I have a problem with Hibernate.

In Short:

How to configure a ManyToMany association with Hibernate when the relationship has an attribute and we need save, delete and update in cascade?

In Large:

Imagine the following DataBase:

             Super      Mini
                 M______N
                     |
                     attribute

There are 3 tables here:

"Mini", "Super" and "Super_Mini".

Now imagine Super_Mini has 1 attribute for the relation (and obviously the keys).

Ok, now this is translating to Hibernate by the following:

 Super:
 // The relation is Many to Many, but considering that it has an attribute, this is OneToMany with the ManyMany RelationShip
 @OneToMany(mappedBy="mini", targetEntity=Mini.class)   
 @Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE})    
 @LazyCollection(LazyCollectionOption.TRUE)
 private Set<SuperMini> superMini = new HashSet<SuperMini>();


 SuperMini:
 @Id    
 @ManyToOne(targetEntity=Super.class,fetch=FetchType.LAZY)  
 @Cascade({CascadeType.LOCK})   
 @JoinColumns({ @JoinColumn(name="...", referencedColumnName="...") })  
 private Super super;   

 @Id    
 @ManyToOne(targetEntity=Mini.class,fetch=FetchType.LAZY)   
 @Cascade({CascadeType.LOCK})   
 @JoinColumns({ @JoinColumn(name="...", referencedColumnName="...") })  
 private Mini mini;

So, I think the configuration is correct, and the save, independently if the object has Mini childrens save all of them. The problem is when I try to delete the object:

 Super data = getHibernateTemplate().load(Super.class, idSuper);

 getHibernateTemplate().getSessionFactory().getCurrentSession().clear();

 data.setMini( new HashSet<Mini>() );

 getHibernateTemplate().delete( data );
 getHibernateTemplate().getSessionFactory().getCurrentSession().flush();

Hibernate don´t delete the Mini relation... What´s the problem? I know how to solve it by HQL, but maybe the configuration is not correct, I don´t know.

Thank you in advance,


Solution

  • Your question is not clear. Super does not contain a Set<Mini2>. It contains a Set<SuperMini2>. So the last code snippet doesn't make much sense.

    Moreover, the targetEntity attribute on Super.superMini2 is incorrect, and unnecessary.

    CascadeType.ALL include CascadeType.DELETE, so it's also unnecessary.

    But to answer your question, I think the problem is that deleting Super cascades to SuperMini2 because the association has a cascade delete, but there is no cascade delete between SuperMini2 and Mini2, so of course, Mini2 instances are not deleted.

    EDIT:

    The answer is that the OP, before editing the question, removed all the entities from the collection of SuperMini before deleting the Super entity. So the cascade delete on the collection of Supermini didn't have anything to delete anymore.