问题
I have a @ManyToMany (bi-directional) relationship between Item and Category.
class Item {
@ManyToMany(cascade = CascadeType.ALL)
Collection<Category> categories=new ArrayList<Category>();
}
class Category {
@ManyToMany(mappedBy="categories", cascade = CascadeType.ALL)
Collection<Item> items=new ArrayList<Item>();
}
I have specified CascadeType.ALL on both. Item is the owner. ManyToMany relationship would be mapped using a third table (Item_Category)
When i create an item and add categories to that item and save the item all the categories within that item get persisted. Also necessary entries are made in the join table (as expected).
However, when i create a category and add new items to it and i save the category i see that necessary entries are made in Item and category tables but no inserts in the Item_Category join table. As a result, the association is not created correctly.
Is this expected behavior? Meaning the association table will have entries only if we add categories in Item as Item is the owner of the relationship?
回答1:
You're expecting magic, and Hibernate isn't that. Saving a broken object model will leave things broken. If Item and Category have a bidirectional relationship, then you must always set both ends of the relationship. Just because you have Hibernate doesn't mean your code can be lazy.
To put it another way, you'd never write code like this and expect it to work, would you (assuming a working assert
keyword)?
Category c = new Category();
Item i = new Item();
c.getItems().add(i);
assert i.getCategories().contains(c);
If not, why do you expect it to work when you add Hibernate to the mix?
回答2:
From Hibernate ORM documentation's site: Example 7.27. Many to many association:
> Changes made only to the inverse end of the association are not persisted <
inverse end meaning not-owning side if you prefer. So yes, you should call the persist method of the relationship-owning side to persist the Item_Category table altogether.
来源:https://stackoverflow.com/questions/14917122/cascade-all-from-non-owning-entity-side