I have an entity A
that has a collection of basic types (e.g. String
). I use such a mapping because the strings associated to each instance of A
depend on A
's lifecycle. If I want to remove an instance of A
from the DB, I also want its associated String
s to be removed.
My mapping is as follows:
@Entity
public class A {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name = "name", nullable = false, unique = true)
private String name;
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "AStrings", joinColumns = @JoinColumn(name = "id"))
@Column(name = "strings", nullable = false)
private Set<String> strings;
}
If I create an instance of A
and add it some strings, then I can persist the instance using Session.save(myInstance)
. Both the instance of A
and its associated String
s are persisted.
But, if I want to remove the same instance from the DB, using Session.createQuery("delete A a where a.name = ?").setString(0, name).executeUpdate()
, I get a foreign key constraint error:
Cannot delete or update a parent row: a foreign key constraint fails
But, I would expect the associated String
s to be automatically removed before removing the A
's instance, but it seems it's not the case. I also didn't found a way to specify cascade rules.
Is there something wrong with my configuration?
Thanks
EDIT: I've also tried using @Cascade(CascadeType.DELETE)
on the field strings
, and it still doesn't help. By looking at the database, I don't see any ON DELETE
policy for the concerned foreign key.
Someone who had the same issue opened a JIRA: https://hibernate.onjira.com/browse/HHH-4301. A solution (or workaround) has to exist, I can't be the only person that uses @ElementCollection
.
I've solved the issue. I thought that deleting using Session.delete() or using an HQL query was equivalent, but it seems not. Using HQL query, the dependent objects are not automatically deleted, so I get a foreign key constraint error. Using Session.delete() solves the problem. Also, Hibernate doesn't seem to use cascade functionality of the DB since I still don't see any CASCADE policy in the generated DDL, it handles this internally.