Hibernate: другой объект с тем же значением идентификатора уже был связан с сеансом
Возможный дубликат:
Ошибка Hibernate: org.hibernate.NonUniqueObjectException: другой объект с тем же значением идентификатора уже был связан с сеансом
когда я использую DAO.update(userbean), session.SaveOrUpdate(e);
throw Exception: другой объект с тем же значением идентификатора уже был связан с сеансом
функция следующая:
public E save(E e) {
Session session = null;
try {
session = sessionFactory.openSession();
log.debug("session="+session.hashCode()+" save "+e);
session.SaveOrUpdate(e); //here throws exception
session.flush();
}
catch (Exception e1) {
log.err("Cannot open hibernate session "+ e1.getMessage()+" cause : "+e1.getCause());
e1.printStackTrace();
}
finally { if ( session != null ) session.close(); session = null;}
return e ;
}
userbean - это экземпляр класса UserBean
public class UserBean{
private List<GroupBean> groups = new ArrayList<GroupBean> ();
private List<RoleBean> roles = new ArrayList<RoleBean> ();
}
public class GroupBean{
private List<RoleBean> roles = new ArrayList<RoleBean> ();
}
каждая группа имеет список ролей, которые не изменяются.
в базе данных, группа и роль - это многозначное отображение,
например,
у нас есть groupbean # 1, его роли: rolebean # 1, rolebean # 2;
groupbean # 2, роли которых - rolebean # 1.
теперь я создаю новый userbean # 1, это группы groupbean # 1
и если я хочу добавить рольbean # 1 в userbean # 1, он выдает исключение, подобное описанию названия
Я смотрю server.log и обнаруживаю, что когда пользователь DAO.save, заказ saveOrUpdate выглядит следующим образом:
userbean#1
|---|-----------***userbean.groups
| | groupbean#1
| | groupbean.roles
| | rolebean#1 # save relebean#1 the first time
| | ---done rolebean#1
| | ------done all rolebeans of group.roles
| | ---done groupbean#1
| |-----------done all groupbeans of userbean.groups
|---|-----------***userbean.roles
| rolebean#1 # save rolebean#1 the second time, and throws exception here!
| ----done rolebean#1
| .....
|-----------done all rolebeans of userbean.roles
причиной исключения является рольbean # 1, которая была сохранена дважды в сеансе, и их идентификация одинакова.
В функции save (E e), если я использую
session.merge(e);
заменить
session.SaveOrUpdate(e);
не будет генерировать исключение, но рольbean # 1 не привязана к userbean # 1
Кто-нибудь может дать некоторые предложения об этом?
Ответы
Ответ 1
Было бы легче определить точную причину, если мы сможем увидеть код, в котором вы назначаете роль bean как пользователю, так и группе.
В общем, что говорит об исключении, существует две версии этой роли bean (два экземпляра). Первый обновляется, затем Hibernate обращается ко второму и распознает его как тот же идентификатор, но другую отдельную версию роли.
Hibernate не уверен, что это правильно, и в saveOrUpdate он выдает исключение, чтобы вы знали.
Слияние контракта работает по-разному, поскольку предполагается, что вы хотели его снова сохранить (т.е. объединить все мои изменения) и, таким образом, повторно подключить вторую версию, слить все изменения и сохранить любые обновления.
Я писал о SaveOrUpdate vs Merge с более подробной информацией, чтобы объяснить, что происходит.
Если вы хотите использовать SaveOrUpdate, вам нужно будет выяснить, что вы делаете в задании, что приводит к тому, что другой экземпляр роли будет назначен для коллекции ролей пользователя по сравнению с группами.
В противном случае, если эффекты слияния работают для вас (что соответствует стандарту JPA), используйте его.