many-to-many deleting problem with playframework
PlayFramework (JPA, Hibernate). Two entities software
<-m:n->tag
, software
is owner of the relation. And I don't use any cascading
.
I want to delete a tag
which has some softwares in it.
Taking into consideration that software
is owner side, I write in my Tag class:
class Tag {
@Override
public Tag delete() {
for (Software software : this.softwares) {
software.tags.remove(this);
software.save(); // if we delete this, we will have an error - a foreign key constraint fails
}
return super.delete();
开发者_C百科 }
}
It works well now, after I've added line software.save()
.
The question is: why i should do it?
I have another project - without Play Framework - which uses JPA->Hibernate and there I don't have to do it. So what's the difference?
In this link they do not use save() as well.
The code from the example you link to and your code are not exactly the same.
In the code that you linked they are removing a number of elements, but if you read in a comment below they say:
// then merge() and flush()
which will save the changes to the database. They are also doing the removal from the class that owns the relation.
In your scenario, you are removing Tags, while the owner is the other end of the relation. So you use (correctly) software.tags.remove to clean the relation.
Now, if you don't save, the changes are not yet acknowledged by the Entity Manager, and when it tries to remove the Tag this Entity Manager detects the M:N active relation and fails.
The reason is the explicit save of Play, where you have to tell the system the changes to save, which is different from the "default" way Hibernate (JPA) works, where the objects are automatically committed (along changes) when the transaction ends.
精彩评论