W moim app mam te Hibernate odwzorowany typów (przypadek ogólny):Dlaczego program Hibernate próbuje usunąć podczas próby aktualizacji/wstawienia?
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()
przesłonięcia.
Moja aplikacja umożliwia podkręcanie ról (tylko przez sysadmins, nie martw się), a wśród innych pól, pozwala tworzyć nowe reguły ról. Po utworzeniu nowej reguły próbuję utworzyć nowy obiekt RoleRule
i wstawić go do pola roli rules
. Dzwonię pod numer session.update(role)
, aby zastosować zmiany w bazie danych.
Teraz przychodzi brzydkie część ... Hibernacja zdecyduje się wykonać następujące czynności przy zamykaniu transakcji i zaczerwienienie:
- Włóż nową regułę do bazy danych. Doskonały.
- Zaktualizuj inne pola ról (nie kolekcje). Jak na razie dobrze.
- Zaktualizuj istniejące reguły, nawet jeśli nic w nich się nie zmieniło. Mogę z tym żyć.
- Zaktualizuj istniejące zasady ponownie. Oto pasta z dziennika, łącznie z automatycznym komentarza:
/* delete one-to-many row Role.rules */ update ROLE_RULE set ROLE_ID=null where ROLE_ID=? and ROLE_RULE_ID=?
Oczywiście, nie wszystkie pola są NULL, a ta operacja nie powiedzie się spektakularnie.
Czy ktoś może próbować wyjaśnić, dlaczego Hibernate to zrobił? A jeszcze ważniejsze jest to, jak się z tym obchodzę ???
EDIT: Byłem więc pewien, że to było coś zrobić z map, a następnie mój szef, dla kaprysu, usunięty equals()
i hashCode()
w obu klasach, odtworzył je przy użyciu Eclipse i tajemniczo to rozwiązało problem .
Nadal jestem bardzo ciekawa mojego pytania. Czy ktoś może zasugerować, dlaczego Hibernate by to zrobił?
Który sterownik i dialekt są używane? –
aplikacja działa na Oracle 10g, ale to nie powinno mieć znaczenia. – Yuval
Najważniejsze, że w twoim poście brakuje implementacji metod 'równy' i' hashCode'. Budowanie metod 'równy' i' hashCode' w oparciu o wartości tożsamości bazy danych ** generowane przez hibernację lub bazę danych ** jest złym pomysłem, przez co są one zależne od dowolnego pola, które można zaktualizować po jeszcze gorszym czasie budowy. –