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