问题
yet another many-to-many Hibernate questions. I have the simplest possible many-to-many mapping as follows:
@Entity
public class Strategy implements Serializable {
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "STRATEGY_TO_GROUP", joinColumns = {@JoinColumn(name="STRATEGY_ID")}, inverseJoinColumns = {@JoinColumn(name = "STRATEGY_GROUP_ID")})
private Set<StrategyGroup> groups;
...
}
And the opposite side of the relation as follows:
@Entity
public class StrategyGroup implements Serializable {
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "STRATEGY_TO_GROUP", joinColumns = {@JoinColumn(name="STRATEGY_GROUP_ID")}, inverseJoinColumns = {@JoinColumn(name = "STRATEGY_ID")})
private Set<Strategy> strategies = new HashSet<Strategy>();
What I want to do now is empty both tables in the easiest possible way. I am trying following (em is my entityManager).
em.createQuery("delete from StrategyGroup sg").executeUpdate();
em.createQuery("delete from Strategy s").executeUpdate();
This gives me constraint violation on the @joinTable. On the other hand if I delete by em.remove(strategyGroup);
ti works fine - the strategy group gets deleted and the @joinTable is updated correctly.
So how do I empty the table? Do I need to load the objects and delete them one by one?
Thanks for help.
回答1:
First of all, your mapping is wrong. One side of the association must be the owner side, and define the mapping of the association. The other must be the inserse side, and just use the mappedBy attribute:
@ManyToMany(fetch = FetchType.EAGER, mappedBy = "groups")
private Set<Strategy> strategies = new HashSet<Strategy>();
Second, you should really avoid EAGER fetching on a toMany association, and particularly on both sides: this will force Hibernate to load all the associated entities recursively, and has a good chance to load all the rows of both tables in memory each time you load one row.
Now to your question:
If you want to delete everything from both tables, you first need to make sure that the join table is empty, else some rows in one of the tables will still be referenced by a row of the join table, and it will obviosuly fail. To do that, the best option in your case is to use a SQL query to delete everything from the join table before executing the two HQL queries you already have.
来源:https://stackoverflow.com/questions/11153135/hibernate-batch-delete-on-many-to-many-table