2011-01-02 12 views
5

Używam implementacji JPA2 i Hibernate.Usuwanie z tabeli z adnotacją @OneToOne

Mam proste mapowanie tak:

@Entity 
class Topic { 

    @Id 
    @GeneratedValue(strategy = IDENTITY) 

    int id; 

    @OneToOne(cascade = ALL) 
    @JoinColumn(name = "id_poll") 
    private Poll poll; 

} 

@Entity 
class Poll { 
    @Id 
    @GeneratedValue(strategy = IDENTITY) 
    int id; 
} 

Teraz, kiedy usunąć obiekt Sonda, która jest również w temacie pojawia się błąd.

java.sql.SQLException: Integrity ograniczenie naruszenie stół FKCC42D924982D3F4B [? Usuwać z sondaży, gdzie id =] tematów na rachunku

Rozumiem, że to dlatego, że nie można usunąć rekordu Sonda jeśli ma odniesienia w innej tabeli. Jak mogę rozwiązać ten problem? Czy muszę ręcznie ustawić poll = null w tabeli tematów, czy jest lepsze rozwiązanie?

Odpowiedz

5

Jest to oczekiwane zachowanie:

Powszechnym problemem z dwukierunkowych relacji jest zastosowanie aktualizacje jedna strona związku, ale z drugiej strony nie dostać zaktualizowane, a staje zsynchronizowane. W JPA, podobnie jak w Javie ogólnie, jest odpowiedzialna za aplikację lub model obiektu w celu zachowania relacji.

Źródło: Object corruption, one side of the relationship is not updated after updating the other side

odpowiednim miejscu obsłużyć to w zwrotnego @PreRemove:

@Entity 
class Poll { 

    ... 

    @PreRemove 
    private void preRemove() { 
     Poll poll = topic.getPoll(); 
     topic.setPoll(null); 
    } 
} 

Zobacz także: Have JPA/Hibernate to replicate the “ON DELETE SET NULL” functionality

1

Wygląda na to, że adnotacja @OneToOne w WZP 2 zawiera flagę osierocenia, możesz spróbować ustawić ją i sprawdzić, czy usuwa ją z wdziękiem.

+1

nope, próbowałem to i nadal robi” t działa .. nadal mam ten sam błąd .. – Dawid

1

Nie udało mi się znaleźć rozwiązania, więc przed usunięciem obiektu ankiety zawsze otrzymuję obiekt tematu, który zawiera daną pulę i ustawia go na wartość null.

Topic topic = entityManager.find(Topic.class, 1); 
Poll poll = topic.getPoll(); 
topic.setPoll(null); 
entityManager.remove(poll); 

Działa poprawnie.

0

Problem polega na tym, że po obu stronach używasz automatycznie wygenerowanego identyfikatora. Gdy utrzymujesz obiekt nadrzędny, obiekt podrzędny jest również zachowywany, ale jego identyfikator w jednostce nadrzędnej nie jest aktualizowany przez ten wygenerowany z bazy danych.

W rezultacie, po usunięciu rodzica, nie usuniesz dziecka, ponieważ dziecko nie ma identyfikatora.

Spróbuj ręcznie ustawić identyfikator elementu podrzędnego i element osierocony będzie działał.

Powiązane problemy