У меня есть класс User, где я хочу, чтобы отношение ManyToMany ссылалось на себя - я решаю, что пользователь может следовать / следовать за другим пользователем. Нет необходимости в других атрибутах, поэтому это должна быть одна таблица с составным первичным ключом. Вот как это аннотируется:
@ManyToMany(cascade = {CascadeType.ALL, CascadeType.MERGE})
@JoinTable(name = "user_followers", joinColumns = { @JoinColumn(name = "follower") }, inverseJoinColumns = { @JoinColumn(name = "following") })
private Set<User> following = new HashSet<User>();
@ManyToMany(mappedBy = "following")
private Set<User> followers = new HashSet<User>();
Все нормально - таблица сформирована, ПК составной follower_following. Когда я сохраняю данные с первой попытки, это работает - выполняется инструкция вставки. НО во второй раз он все еще пытается вставить ранее выполненное отношение (очевидно, не то же самое), и я получаю:
Unexpected RuntimeException
Last cause: Duplicate entry 'follower-following' for key 'PRIMARY'
// EDIT: There are correct FK keys instead of follower-following
Вот как я добавляю последователя и сохраняю пользователя:
if (!user.following.contains(toFollowUser)) {
user.following.add(toFollowUser);
}
if (session.contains(user)) {
session.persist(user);
} else {
session.merge(user)
}
session.getTransaction().commit(); // HERE I get exception
С моей точки зрения, похоже, что Hibernate не видит, что предыдущее отношение было сохранено и записано в базу данных, и все еще пытается вставить новую запись, которая, конечно, попадает в дублированный ключ. Ты хоть представляешь, что я делаю не так?
Это означает другую транзакцию, она разделяется HTTP-запросом (я использую Wicket). Первый выполняется и закрывается, затем следует второй.




Может быть несвязанным, но «if (session.contains (user) -> persist» неверно, если сеанс уже содержит объект, объект прикреплен, поэтому вам не нужно вызывать persist для него (простое изменение объекта вызовет изменения будут сброшены после вызова коммита). Кстати, что вы имеете в виду под первым и вторым разом? разными транзакциями? одной и той же транзакцией?