JPA / Hibernate Usuń encję czasami nie działa
Mam następujący kod, który zwykle działa dobrze:
public void delete(T object)
{
EntityManager em = getPersistence().createEntityManager();
EntityTransaction et = em.getTransaction();
try
{
et.begin();
object = em.find(object.getClass(), object.getId());
em.remove(object);
em.flush();
et.commit();
}
catch(Exception e)
{
error("Unable to delete " + object.toString() + ": there are references to it.");
}
finally
{
if (et.isActive()) et.rollback();
em.close();
}
}
Dla wielu moich klas Bytów to po prostu działa. Jednak dla dwóch z nich nie robi nic, nie wyrzuca żadnych WYJĄTKÓW i nie usuwa obiektu. Dziennik z hibernate pokazuje, że hibernate wykonuje szereg zapytań select, ale nawet nie próbuje wykonać delete.
Próbowałem już sugestii znalezionych w innych podobnych pytaniach tutaj i tutaj , ale bezskutecznie (dobrze, ten ostatni sugeruje @Transactional
, którego nie mogę użyć, ale zamiast tego umieściłem wyrażenia pomiędzy begin()
i commit()
).
Wydaje mi się, że nie mogę znaleźć tego, co te dwie klasy mają więcej (lub mniej) niż inne. Używają @PrimaryKeyJoinColumn
tak jak prawie wszystkie inne byty, które mam, mają @OneToMany
i @ManyToOne
tak jak ohters. Szczerze mówiąc, mają pole @OneToOne(optional = false)
, które odwołuje się do innej klasy, A innych encji nie ma, ale nie przechodziłbym przez kłopoty ze zmianą tego (i w konsekwencji zmienianiem schemat bazy danych), chyba że powiesz mi, że może być ku temu powód.
Czy @OneToOne
jest odpowiedzialny? A może mój kod jest na podsłuchu?
3 answers
Czy masz skojarzenia na tym wykresie, które kaskadują persist z powrotem do rzeczy usuwanej? Jeśli tak, Specyfikacja JPA wyraźnie stwierdza, że dostawca ma anulować usunięcie w takim przypadku. W takim przypadku Hibernate wypisuje instrukcję logu " un-scheduling entity deletion [...]". Możesz to zobaczyć, włączając rejestrowanie śladów na org.hibernate.event.internal.DefaultPersistEventListener
loggerze.
Jeśli taka jest sytuacja, musisz wyczyścić te skojarzenia zgodnie ze specyfikacją JPA.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-02 08:13:14
Zastąpienie cascade = CascadeType.ALL
przez orphanRemoval = true
w asocjacji @OneToMany
daje oczekiwany wynik: rekordy potomne są poprawnie usuwane bez konieczności usuwania rekordu nadrzędnego.
Szkoda, że błąd nie jest rejestrowany wyraźniej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-13 16:06:23
Mam ten sam problem, gdy śledzę rzeczy zebrane razem.
- Hibernate 3.6.10.Finał
- podmiot macierzysty zBez odniesienia do dziecka.
-
Jakiś element potomny w odniesieniu do rodzica. Jest to kod legacy.
class ChildEntity { @ManyToOne(cascade = CascadeType.ALL) private ParentEntity parent; }
-
Obiekt potomny jest ładowany do kontekstu sesji, a następnie usuwany z tabeli bez powiadomienia JPA w ramach transakcji (procedura składowana, natywny sql)
Wtedy rodzica nie można usunąć. Bez usuwania, nie wyjątek, po prostu wiadomość "anuluj usuwanie harmonogramu" w dzienniku śledzenia.
Rozwiązanie: usunąłem atrybut cascade. Trochę trudno było mi znaleźć, która Jednostka potomna blokuje usunięcie rodzica. Również, nie rozumiem, dlaczego kaskada dzieci wpływa, jeśli usunąć podmiot macierzysty.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-17 15:35:13