Dlaczego Hibernate próbuje usunąć, gdy próbuję zaktualizować / wstawić?
W mojej aplikacji mam te typy mapowane Hibernate (przypadek ogólny):
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;
}
}
Wszystkie klasy mająequals() & hashCode()
nadpisania.
Moja aplikacja umożliwia modyfikowanie ról (tylko przez administratorów, nie martw się), a między innymi umożliwia tworzenie nowych reguł ról. Po utworzeniu nowej reguły próbuję utworzyć nowąRoleRule
obiekt i wstaw go do pola rolirules
. Dzwonięsession.update(role)
aby zastosować zmiany w bazie danych.
Teraz pojawia się brzydka część ... Hibernate postanawia wykonać następujące czynności podczas zamykania transakcji i spłukiwania:
Wstaw nową regułę do bazy danych. Doskonały.Zaktualizuj pozostałe pola ról (nie kolekcje). Jak na razie dobrze.Zaktualizuj istniejące reguły, nawet jeśli nic się w nich nie zmieniło. Mogę z tym żyć.Zaktualizuj istniejące zasadyjeszcze raz. Oto wklej z dziennika, w tym automatyczny komentarz:/* delete one-to-many row Role.rules */ update ROLE_RULE set ROLE_ID=null where ROLE_ID=? and ROLE_RULE_ID=?
Oczywiście wszystkie pola nie są zerowe i operacja ta kończy się niepowodzeniem.
Czy ktoś może wyjaśnić, dlaczego Hibernate to zrobił? A co ważniejsze, jak sobie radzę z frakiem?
EDYTOWAĆ: Byłem tak pewien, że to miało coś wspólnego z mapowaniem, a potem mój szef, z kaprysu, usunąłequals()
ihashCode()
w obu klasach odtworzono je za pomocą Eclipse, a tajemniczo rozwiązało to problem.
Nadal jestem bardzo ciekawa mojego pytania. Czy ktoś może zasugerować, dlaczego Hibernate to zrobił?