В моем приложении у меня есть эти типы, отображаемые в Hibernate (общий случай):
class RoleRule {
private Role role;
private PermissionAwareEntity entity; // hibernate-mapped entity for which permission is granted
private PermissionType permissionType; // enum
@ManyToOne
@JoinColumn(name = "ROLE_ID")
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
}
class Role {
private Set<RoleRule> rules = new HashSet<RoleRule>(0);
@OneToMany(cascade=CascadeType.ALL)
@JoinColumn(name="ROLE_ID")
public Set<RoleRule> getRules() {
return rules;
}
public void setRules(Set<RoleRule> rules) {
this.rules = rules;
}
}
Все классы имеют equals() & hashCode()
переопределения.
Мое приложение позволяет настраивать роли (только для системных администраторов, не волнуйтесь), а также среди других полей позволяет создавать новые правила ролей. Когда создается новое правило, я пытаюсь создать новый объект RoleRule
и вставить его в поле роли rules
. Я звоню session.update(role)
, чтобы применить изменения к базе данных.
Теперь наступает ужасная часть ... Hibernate решает сделать следующее при закрытии транзакции и сбросе:
- Вставить новое правило в базу данных. Отлично.
- Обновите другие поля ролей (не коллекции). Пока все хорошо.
- Обновите существующие правила, даже если в них ничего не изменилось. Я могу жить с этим.
- Обновите существующие правила , снова . Вот вставка из журнала, включая автоматический комментарий:
/* delete one-to-many row Role.rules */
update ROLE_RULE set ROLE_ID=null where ROLE_ID=? and ROLE_RULE_ID=?
Конечно, все поля не равны NULL, и эта операция завершается неудачно.
Может кто-нибудь попытаться объяснить, почему Hibernate сделал бы это ??? И что еще важнее, как мне это обойти?
РЕДАКТИРОВАТЬ : Я был настолько уверен, что это было связано с отображением, и затем мой босс по прихоти удалил equals()
и hashCode()
в обоих классах, воссоздав их с помощью Eclipse и загадочно это решило проблему.
Мне все еще очень любопытен мой вопрос. Кто-нибудь может подсказать, почему Hibernate сделал бы это?