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?

Author: Community, 2013-06-03

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.

 69
Author: Steve Ebersole,
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.

 22
Author: Arthur Nederlof,
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.

  1. Hibernate 3.6.10.Finał
  2. podmiot macierzysty zBez odniesienia do dziecka.
  3. Jakiś element potomny w odniesieniu do rodzica. Jest to kod legacy.

    class ChildEntity {
      @ManyToOne(cascade = CascadeType.ALL)
      private ParentEntity parent;
    }
    
  4. Obiekt potomny jest ładowany do kontekstu sesji, a następnie usuwany z tabeli bez powiadomienia JPA w ramach transakcji (procedura składowana, natywny sql)

  5. 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.

 4
Author: Andriy Slobodyanyk,
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