Hibernate i Cascade Delete

Hibernate i Cascade Delete
RezyserKinaAkcji
  • Rejestracja:prawie 5 lat
  • Ostatnio:około 2 lata
  • Postów:163
0

Cześć. Posiadam dwie encje, będące ze sobą w relacji OneToMany. Chciałbym usuwając rodzica usuwać także dzieci, jednak SQL ma z tym jakiś problem

Kopiuj
java.sql.SQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`pickmeup_database`.`offered_ride`, CONSTRAINT `offered_ride_ibfk_1` FOREIGN KEY (`id_user`) REFERENCES `user` (`id_user`))

Schemat bazy

title

OfferedRide.class

Kopiuj
@Entity
@Table(name="offered_ride")
public class OfferedRide {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="id_offered_ride")
    @JsonView({View.User.class, View.ActivationCode.class, View.OfferedRide.class, View.Seat.class})
    private int id_offered_ride;

    @Column(name="date_of_ride")
    @JsonView({View.User.class, View.ActivationCode.class, View.OfferedRide.class, View.Seat.class})
    private Date date_of_ride;

    @Column(name="time_of_ride")
    @JsonView({View.User.class, View.ActivationCode.class, View.OfferedRide.class, View.Seat.class})
    private Time time_of_ride;

    @Column(name="number_of_free_seats")
    @JsonView({View.User.class, View.ActivationCode.class, View.OfferedRide.class, View.Seat.class})
    private int number_of_free_seats;

    @Column(name="ride_category")
    @JsonView({View.User.class, View.ActivationCode.class, View.OfferedRide.class, View.Seat.class})
    private int ride_category;

    @Column(name="from_where")
    @JsonView({View.User.class, View.ActivationCode.class, View.OfferedRide.class, View.Seat.class})
    private String from_where;

    @Column(name="to_where")
    @JsonView({View.User.class, View.ActivationCode.class, View.OfferedRide.class, View.Seat.class})
    private String to_where;

    @Column(name="user_comment")
    @JsonView({View.User.class, View.ActivationCode.class, View.OfferedRide.class, View.Seat.class})
    private String user_comment;

    @ManyToOne(cascade= {CascadeType.PERSIST, CascadeType.MERGE,
            CascadeType.DETACH, CascadeType.REFRESH})
    @JoinColumn(name="id_user")
    @JsonView({View.OfferedRide.class, View.Seat.class})
    private User user;

    @OneToMany(mappedBy="offeredRide",
            cascade= {CascadeType.ALL})
    @JsonView({View.User.class})
    private List<Seat> listOfSeats;

    public OfferedRide() {

    }

User.class

Kopiuj
@Entity
@Table(name = "user")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id_user")
    @JsonView({View.ActivationCode.class, View.User.class, View.OfferedRide.class, View.Seat.class})
    private int id_user;

    @OneToOne(cascade = {CascadeType.DETACH,
            CascadeType.MERGE,
            CascadeType.PERSIST,
            CascadeType.REFRESH})
    @JoinColumn(name = "id_activation_code")
    @JsonView({View.User.class})
    private ActivationCode activationCode;

    @Column(name = "user_name")
    @JsonView({View.ActivationCode.class, View.User.class, View.OfferedRide.class, View.Seat.class})
    private String user_name;

    @Column(name = "user_surname")
    @JsonView({View.ActivationCode.class, View.User.class, View.OfferedRide.class, View.Seat.class})
    private String user_surname;

    @Column(name = "user_email")
    @JsonView({View.ActivationCode.class, View.User.class, View.OfferedRide.class, View.Seat.class})
    private String user_email;

    @Column(name = "user_password")
    @JsonView({View.ActivationCode.class, View.User.class})
    private String user_password;

    @Column(name = "user_phone_number")
    @JsonView({View.ActivationCode.class, View.User.class, View.OfferedRide.class, View.Seat.class})
    private String user_phone_number;

    @Column(name = "user_car")
    @JsonView({View.ActivationCode.class, View.User.class, View.OfferedRide.class, View.Seat.class})
    private String user_car;

    @Column(name = "user_description")
    @JsonView({View.ActivationCode.class, View.User.class, View.OfferedRide.class, View.Seat.class})
    private String user_description;

    @Column(name = "is_active")
    @JsonView({View.ActivationCode.class, View.User.class})
    private boolean is_active;

    @OneToMany(mappedBy="user",
            cascade= {CascadeType.ALL})
    @JsonView({View.User.class})
    private List<OfferedRide> listOfUsersOfferedRides;

    @OneToMany(mappedBy="user",
            cascade= {CascadeType.ALL})
    @JsonView({View.User.class})
    private List<Seat> listOfUserSeats;

    public User() {

    }

Metoda usuwająca

Kopiuj
    @Override
    public Response deleteUserById(int theID) {
        Session session = entityManager.unwrap(Session.class);
        Response response = new Response();
        User user;
        try {
            user = session.get(User.class, theID);
        } catch (NoResultException ex) {
            response.setMsg("User with ID " + theID + " not found");
            response.setSuccesful(false);
            return response;
        }
        if(user != null){
            Query query = session.createQuery("DELETE FROM User user WHERE user.id_user = " + theID);
            query.executeUpdate();
            response.setSuccesful(true);
            response.setMsg("User with ID " + theID + " successfully deleted");
        } else {
            response.setMsg("User with ID " + theID + " not found");
            response.setSuccesful(false);
        }
        return response;
    }

Próbowałem wielu rozwiązań, stackoverflow itp, ale nic nie działa. Cały czas SQL pluje się, że probuje usunąć obiekt który jest kluczem obcym innego obiektu, mimo, że zaznaczone jest wyraźnie CascadeType.ALL

Czy ktoś może ma jakiś pomysł ?

edytowany 1x, ostatnio: RezyserKinaAkcji
Korges
Piekło adnotacji. Developer swoim ostatni krzykiem rozpaczy wydał rozkaz istotom Beliara. Brzmiał on „PRZYBYWAJCIE!” i przybyły wszystkie, nawet smoki.
Charles_Ray
  • Rejestracja:około 17 lat
  • Ostatnio:około 17 godzin
  • Postów:1875
1

Wydaje mi się, że bulk delete nie wywołuje kaskady. Musisz użyć remove() na sesji/EntityManagerze.


”Engineering is easy. People are hard.” Bill Coughran
99xmarcin
  • Rejestracja:około 5 lat
  • Ostatnio:6 miesięcy
  • Postów:2420
1

Cascade delete jest obsługiwany nie przez Hiberante ale na poziomie bazy danych. Czy na pewno masz w schemacie bazy danych odpowiednio ustawione CASCADE DELETE na kluczach obcych (powinno być coś w stylu ON DELETE CASCADE)?


Holy sh*t, with every month serenityos.org gets better & better...
edytowany 1x, ostatnio: 99xmarcin
RezyserKinaAkcji
  • Rejestracja:prawie 5 lat
  • Ostatnio:około 2 lata
  • Postów:163
0

@0xmarcin:

Oj raczej nie. Tak wygląda mój plik tworzący bazę danych

Kopiuj
CREATE TABLE `activation_code` (
  `id_activation_code` int(11) NOT NULL,
  `serial_number` varchar(15) COLLATE utf8mb4_polish_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_polish_ci;

-- --------------------------------------------------------

--
-- Struktura tabeli dla tabeli `offered_ride`
--

CREATE TABLE `offered_ride` (
  `id_offered_ride` int(11) NOT NULL,
  `id_user` int(11) NOT NULL,
  `date_of_ride` date NOT NULL,
  `time_of_ride` time NOT NULL,
  `number_of_free_seats` int(2) NOT NULL,
  `ride_category` int(1) NOT NULL,
  `from_where` varchar(100) COLLATE utf8mb4_polish_ci NOT NULL,
  `to_where` varchar(100) COLLATE utf8mb4_polish_ci NOT NULL,
  `user_comment` varchar(250) COLLATE utf8mb4_polish_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_polish_ci;

-- --------------------------------------------------------

--
-- Struktura tabeli dla tabeli `seat`
--

CREATE TABLE `seat` (
  `id_seat` int(11) NOT NULL,
  `id_offered_ride` int(11) NOT NULL,
  `id_user` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_polish_ci;

-- --------------------------------------------------------

--
-- Struktura tabeli dla tabeli `user`
--

CREATE TABLE `user` (
  `id_user` int(11) NOT NULL,
  `id_activation_code` int(11) NOT NULL,
  `user_name` varchar(20) COLLATE utf8mb4_polish_ci NOT NULL,
  `user_surname` varchar(30) COLLATE utf8mb4_polish_ci NOT NULL,
  `user_email` varchar(30) COLLATE utf8mb4_polish_ci NOT NULL,
  `user_password` varchar(30) COLLATE utf8mb4_polish_ci NOT NULL,
  `user_phone_number` varchar(15) COLLATE utf8mb4_polish_ci NOT NULL,
  `user_car` varchar(100) COLLATE utf8mb4_polish_ci NOT NULL,
  `user_description` varchar(250) COLLATE utf8mb4_polish_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_polish_ci;

-- --------------------------------------------------------

--
-- Struktura tabeli dla tabeli `wanted_ride`
--

CREATE TABLE `wanted_ride` (
  `id_wanted_ride` int(11) NOT NULL,
  `id_user` int(11) NOT NULL,
  `date_of_ride` date NOT NULL,
  `time_of_ride` time NOT NULL,
  `ride_category` int(2) NOT NULL,
  `from_where` varchar(100) COLLATE utf8mb4_polish_ci NOT NULL,
  `to_where` varchar(100) COLLATE utf8mb4_polish_ci NOT NULL,
  `user_comment` varchar(250) COLLATE utf8mb4_polish_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_polish_ci;

--
-- Indeksy dla zrzutów tabel
--

--
-- Indeksy dla tabeli `activation_code`
--
ALTER TABLE `activation_code`
  ADD PRIMARY KEY (`id_activation_code`);

--
-- Indeksy dla tabeli `offered_ride`
--
ALTER TABLE `offered_ride`
  ADD PRIMARY KEY (`id_offered_ride`),
  ADD KEY `id_user` (`id_user`);

--
-- Indeksy dla tabeli `seat`
--
ALTER TABLE `seat`
  ADD PRIMARY KEY (`id_seat`),
  ADD KEY `id_wanted_ride` (`id_offered_ride`),
  ADD KEY `id_user` (`id_user`);

--
-- Indeksy dla tabeli `user`
--
ALTER TABLE `user`
  ADD PRIMARY KEY (`id_user`),
  ADD KEY `id_activation_code` (`id_activation_code`);

--
-- Indeksy dla tabeli `wanted_ride`
--
ALTER TABLE `wanted_ride`
  ADD PRIMARY KEY (`id_wanted_ride`),
  ADD KEY `id_user` (`id_user`);

--
-- AUTO_INCREMENT for dumped tables
--

--
-- AUTO_INCREMENT dla tabeli `activation_code`
--
ALTER TABLE `activation_code`
  MODIFY `id_activation_code` int(11) NOT NULL AUTO_INCREMENT;

--
-- AUTO_INCREMENT dla tabeli `offered_ride`
--
ALTER TABLE `offered_ride`
  MODIFY `id_offered_ride` int(11) NOT NULL AUTO_INCREMENT;

--
-- AUTO_INCREMENT dla tabeli `seat`
--
ALTER TABLE `seat`
  MODIFY `id_seat` int(11) NOT NULL AUTO_INCREMENT;

--
-- AUTO_INCREMENT dla tabeli `user`
--
ALTER TABLE `user`
  MODIFY `id_user` int(11) NOT NULL AUTO_INCREMENT;

--
-- AUTO_INCREMENT dla tabeli `wanted_ride`
--
ALTER TABLE `wanted_ride`
  MODIFY `id_wanted_ride` int(11) NOT NULL AUTO_INCREMENT;

--
-- Ograniczenia dla zrzutów tabel
--

--
-- Ograniczenia dla tabeli `offered_ride`
--
ALTER TABLE `offered_ride`
  ADD CONSTRAINT `offered_ride_ibfk_1` FOREIGN KEY (`id_user`) REFERENCES `user` (`id_user`);

--
-- Ograniczenia dla tabeli `seat`
--
ALTER TABLE `seat`
  ADD CONSTRAINT `seat_ibfk_1` FOREIGN KEY (`id_user`) REFERENCES `user` (`id_user`),
  ADD CONSTRAINT `seat_ibfk_2` FOREIGN KEY (`id_offered_ride`) REFERENCES `offered_ride` (`id_offered_ride`);

--
-- Ograniczenia dla tabeli `user`
--
ALTER TABLE `user`
  ADD CONSTRAINT `user_ibfk_1` FOREIGN KEY (`id_activation_code`) REFERENCES `activation_code` (`id_activation_code`);

--
-- Ograniczenia dla tabeli `wanted_ride`
--
ALTER TABLE `wanted_ride`
  ADD CONSTRAINT `wanted_ride_ibfk_1` FOREIGN KEY (`id_user`) REFERENCES `user` (`id_user`);
COMMIT;
RezyserKinaAkcji
  • Rejestracja:prawie 5 lat
  • Ostatnio:około 2 lata
  • Postów:163
0

@Charles_Ray: Właśnie próbowałem używać session.remove, to w ogóle miałem problem z usunięciem obiektu, nawet nie powiązanego z niczym

crejk
  • Rejestracja:ponad 6 lat
  • Ostatnio:około 21 godzin
  • Postów:46
1

Spróbuj ustawić orphanRemoval = true

RezyserKinaAkcji
Próbowałem. Ten sam error
S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:6 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
1

Zgadzam się z @Charles_Ray, o ile nic z biblii JPA nie zapomniałem. Delete na EM music być


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
RezyserKinaAkcji
  • Rejestracja:prawie 5 lat
  • Ostatnio:około 2 lata
  • Postów:163
0

@scibi92: Próbowałem na 3 sposoby

Kopiuj
        if(user != null){
//            Query query = session.createQuery("DELETE FROM User user WHERE user.id_user = " + theID);
//            query.executeUpdate();
//            session.remove(user);
//            session.delete(user);

Niestety ostatnie 2 linijki nie daja rezultatu. Nie usuwa obiektu

S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:6 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
1

IMO jakk korzystasz z JPA to bądź konsekwentny i korzystaj z EntityManagerza


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
RezyserKinaAkcji
  • Rejestracja:prawie 5 lat
  • Ostatnio:około 2 lata
  • Postów:163
0

@scibi92: Nic nie działa, nawet entityManager. Jedyna opcja, żeby usunąć, to hql i DELETE FROM User. Reszta nie przynosi rezultatów. Wiesz może gdzie może być błąd ?

99xmarcin
  • Rejestracja:około 5 lat
  • Ostatnio:6 miesięcy
  • Postów:2420
1

Na moje oko w załączonym schemacie bazy danych NIE MA cascade delete na kluczu obcym. Jeżeli ta baza danych tworzona jest ręcznie to należy dodać te brakujące kaskady. Jeżeli przez Hibernate to należy przegenerować.

Na mój rozum: Usuwasz za pomocą HQL'a a więc bez ładowania encji do pamięci. W tym wypadku Hibernate zmieni to na prosty DELETE SQL'owy i wyśle do bazy, oczekując że jest tam odpowiednia kaskada ustawiona.

Wygeneruj sobie bazę z tego mapowania z Hibernate i porównaj z tym co masz, to powinno Ci uwidocznić różnice.

Warto też sobie na etapie debugowania włączyć logowanie SQLi w Hibernate, przynajmniej będzie widać od razu co ORM chce zrobić.... (https://stackoverflow.com/questions/2536829/hibernate-show-real-sql)

EDIT: Jak słusznie zauważył @Charles_Ray ta odpowiedź nie ma sensu jeżeli mamy ustawione w @OneToMany(cascade=REMOVE) kaskady, bo wtedy Hibernate załaduje i tak powiązane encje do pamięci a następnie pousuwa je (https://thorben-janssen.com/avoid-cascadetype-delete-many-assocations/).
Natomiast odpowiedź jest słuszna jeżeli zrezygnujemy z użycia kaskad (np. ze względu na wydajność i żeby uniknąć problemu select N+1). Wtedy musimy albo sami usuwać powiązane encje albo zrzucić tą odpowiedzialność na bazę....


Holy sh*t, with every month serenityos.org gets better & better...
edytowany 4x, ostatnio: 99xmarcin
RezyserKinaAkcji
Oki, dzięki wielkie, będę się bawił tym jeszcze
Charles_Ray
Mylisz się i to bardzo. Kaskada JPA działa na innym poziomie niż baza. Zanim skomentujesz zajrzyj do dokumentacji.
99xmarcin
@Charles_Ray: ostatni raz z Hibernate pracowałem > 2 lata temu więc moja wiedza mogła trochę przyrdzewieć. Ale nadal dobrze pamiętam problemy z lazy-loadinginem + brak on cascade delete. Patrz też to: https://stackoverflow.com/a/38495206.
Charles_Ray
Piszesz jakieś herezje
Charles_Ray
  • Rejestracja:około 17 lat
  • Ostatnio:około 17 godzin
  • Postów:1875
0

@RezyserKinaAkcji: jaki błąd leci na remove() ?


”Engineering is easy. People are hard.” Bill Coughran
RezyserKinaAkcji
  • Rejestracja:prawie 5 lat
  • Ostatnio:około 2 lata
  • Postów:163
0

@Charles_Ray: Żaden. Wszystko gra, tylko obiekt nie jest usuwany z bazy danych

Charles_Ray
  • Rejestracja:około 17 lat
  • Ostatnio:około 17 godzin
  • Postów:1875
0

Pokaz kod. Masz transakcje otwarta?


”Engineering is easy. People are hard.” Bill Coughran
RezyserKinaAkcji
  • Rejestracja:prawie 5 lat
  • Ostatnio:około 2 lata
  • Postów:163
0

@Charles_Ray:

UserDAO.class

Kopiuj
    @Override
    public Response deleteUserById(int theID) {
        Session session = entityManager.unwrap(Session.class);
        Response response = new Response();
        User user;
        try {
            user = session.get(User.class, theID);
        } catch (NoResultException ex) {
            response.setMsg("User with ID " + theID + " not found");
            response.setSuccesful(false);
            return response;
        }
        if(user != null){
            Query query = session.createQuery("DELETE FROM User user WHERE user.id_user = " + theID);
            query.executeUpdate();
            response.setSuccesful(true);
            response.setMsg("User with ID " + theID + " successfully deleted");
        } else {
            response.setMsg("User with ID " + theID + " not found");
            response.setSuccesful(false);
        }
        return response;
    }

UserService.class

Kopiuj
    @Override
    @Transactional
    public Response deleteUserById(int theID) {
        return userDAO.deleteUserById(theID);
    }

UserRestController.class

Kopiuj
    @DeleteMapping("/user/delete/{theID}")
    public Response deleteUserById(@PathVariable int theID){
        return userService.deleteUserById(theID);
    }
Zobacz pozostałe 3 komentarze
jarekr000000
Tylko tu cały czas nie ma tego prostego remove, które powinno załatwić problem.
RezyserKinaAkcji
@Charles_Ray: tak byłem uczony przez instruktora na udemy.com
RezyserKinaAkcji
@jarekr000000: próbowałem z remove na session i na entityManagerze. Nie wyrzucało błędu, ale obiektu z bazy też nie wyrzucało
jarekr000000
@RezyserKinaAkcji: to pokaż (zrób taki kod z remove(...)), sprawdź. Jak nie zadziała to zgłosimy błąd do Hibernate :-)
99xmarcin
  • Rejestracja:około 5 lat
  • Ostatnio:6 miesięcy
  • Postów:2420
0

Być może ugryzł Ciebie też błąd opisany tutaj: https://www.baeldung.com/delete-with-hibernate#deletion-using-the-entity-manager

Spróbuj usunąć dla przykładu bez wcześniejszego wczytywania encji użytkownika.


Holy sh*t, with every month serenityos.org gets better & better...
Charles_Ray
Litości :D przecież usuwana encja musi być managed
99xmarcin
Chodzi mi o to żeby zakomentować: user = session.get(User.class, theID); :P
RezyserKinaAkcji
  • Rejestracja:prawie 5 lat
  • Ostatnio:około 2 lata
  • Postów:163
0

@jarekr000000:

Kopiuj
    @Override
    public Response deleteUserById(int theID) {
        Session session = entityManager.unwrap(Session.class);
        Response response = new Response();
        User user;
        try {
            user = session.get(User.class, theID);
        } catch (NoResultException ex) {
            response.setMsg("User with ID " + theID + " not found");
            response.setSuccesful(false);
            return response;
        }
        if(user != null){
//            Query query = session.createQuery("DELETE FROM User user WHERE user.id_user = " + theID);
//            query.executeUpdate();
            entityManager.remove(user);
            response.setSuccesful(true);
            response.setMsg("User with ID " + theID + " successfully deleted");
        } else {
            response.setMsg("User with ID " + theID + " not found");
            response.setSuccesful(false);
        }
        return response;
    }

title

title

To samo dzieje się, kiedy remove wywołuje na session, nie na entityManagerze. W konsoli żadnego błędu ze strony Springa ani Hibernate'a

edytowany 1x, ostatnio: RezyserKinaAkcji
jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około godziny
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4707
1

Jaka to wersja hibernate?
Trzeba buga zgłosić

Ale możesz jeszcze na wszelki wypadek zrobić disconnect / connect do bazy danych (z tego narzędzia) i sprawdzić czy na pewno nie znikło.


jeden i pół terabajta powinno wystarczyć każdemu
edytowany 1x, ostatnio: jarekr000000
Zobacz pozostałe 3 komentarze
RezyserKinaAkcji
@0xmarcin: zrobiłem to, ten sam błąd. A remove nadal nie usuwa
99xmarcin
@RezyserKinaAkcji: na pewno ten sam? Nie mówi teraz o innym kluczu obcym?
RezyserKinaAkcji
@0xmarcin: ten sam, identyczny
99xmarcin
W takim razie niestety nie mogę pomóc @RezyserKinaAkcji, moja teoria updała. Rada jarekr żeby zrobić mały przykład który to reprodukuje i umiejścić na GitHubie jest jak najbardziej na miejscu...
RezyserKinaAkcji
@0xmarcin: jasne, dzięki za chęci !
RezyserKinaAkcji
  • Rejestracja:prawie 5 lat
  • Ostatnio:około 2 lata
  • Postów:163
0

@jarekr000000:

Kopiuj
2020-11-12 15:51:28.776  INFO 19080 --- [         task-1] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 5.4.22.Final

User.class

Kopiuj
@Entity
@Table(name = "user")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id_user")
    @JsonView({View.ActivationCode.class, View.User.class, View.OfferedRide.class, View.Seat.class, View.WantedRide.class})
    private int id_user;

    @OneToOne(cascade = {CascadeType.DETACH,
            CascadeType.MERGE,
            CascadeType.PERSIST,
            CascadeType.REFRESH})
    @JoinColumn(name = "id_activation_code")
    @JsonView({View.User.class})
    private ActivationCode activationCode;

    @Column(name = "user_name")
    @JsonView({View.ActivationCode.class, View.User.class, View.OfferedRide.class, View.Seat.class, View.WantedRide.class})
    private String user_name;

    @Column(name = "user_surname")
    @JsonView({View.ActivationCode.class, View.User.class, View.OfferedRide.class, View.Seat.class, View.WantedRide.class})
    private String user_surname;

    @Column(name = "user_email")
    @JsonView({View.ActivationCode.class, View.User.class, View.OfferedRide.class, View.Seat.class, View.WantedRide.class})
    private String user_email;

    @Column(name = "user_password")
    @JsonView({View.ActivationCode.class, View.User.class})
    private String user_password;

    @Column(name = "user_phone_number")
    @JsonView({View.ActivationCode.class, View.User.class, View.OfferedRide.class, View.Seat.class, View.WantedRide.class})
    private String user_phone_number;

    @Column(name = "user_car")
    @JsonView({View.ActivationCode.class, View.User.class, View.OfferedRide.class, View.Seat.class, View.WantedRide.class})
    private String user_car;

    @Column(name = "user_description")
    @JsonView({View.ActivationCode.class, View.User.class, View.OfferedRide.class, View.Seat.class, View.WantedRide.class})
    private String user_description;

    @Column(name = "is_active")
    @JsonView({View.ActivationCode.class, View.User.class})
    private boolean is_active;

    @OneToMany(mappedBy="user",
            cascade= {CascadeType.ALL})
    @JsonView({View.User.class})
    private List<OfferedRide> listOfUsersOfferedRides;

    @OneToMany(mappedBy="user",
            cascade= {CascadeType.ALL})
    @JsonView({View.User.class})
    private List<Seat> listOfUserSeats;

    @OneToMany(mappedBy="user",
            cascade= {CascadeType.ALL})
    @JsonView({View.User.class})
    private List<WantedRide> listOfWantedRides;



    public User() {

    }

Zrobiłem disconnecta, nadal obiekt jest w bazie. W zasadzie działa tylko query "DELETE FROM User...."

edytowany 1x, ostatnio: RezyserKinaAkcji
jarekr000000
Nie mam pojęcia co może się dziać, tak grubych błędów raczej w hibernate nie ma. Co prawda może być kilka przyczyn dlaczego ten kod remove nie działa, ale zawsze coś by do loga wpadło. Najlepiej jakbyś wypuścił ten kod na github.
Charles_Ray
Dokładnie, coś na poziomie konfiguracji JPA i transakcji może być skopane
jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około godziny
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4707
7

@RezyserKinaAkcji
Problem jest tu w klasie User

Kopiuj
  @OneToOne(cascade = {CascadeType.DETACH,
            CascadeType.MERGE,
            CascadeType.PERSIST,
            CascadeType.REFRESH})
    @JoinColumn(name = "id_activation_code")
    @JsonView({View.User.class})
private ActivationCode activationCode;

zamień to na

Kopiuj
  @OneToOne(cascade = {CascadeType.DETACH,
            CascadeType.MERGE,
            CascadeType.PERSIST,
            CascadeType.REMOVE, //To trzeba było dodać
            CascadeType.REFRESH})
    @JoinColumn(name = "id_activation_code")
    @JsonView({View.User.class})
private ActivationCode activationCode;

i zadziała zwykłe remove na session.

Ciekawostki:
faktycznie, żadnych błędów EntityManger czy Session nie rzucał. Po prostu remove było ignorowane ( obiekt był cichaczem przywracany w czasie flush).
żaden DELETE statement nawet nie leciał do bazy danych.

ActivationCode miał OneToOne do User i zgaduje (bo nie chce mi się głębiej wyjaśniać), że przez to niejako remove kończył się przywróceniem obiektu jeszcze raz (bo ActivationCode nadal trzyma). Usunięcie kaskad od strony ActivationCode też pomaga na problem.

A teraz proszę o wyjasnienia ekspertów od JPA, Hibernate. Chciałbym zrozumieć, że to logiczne.

Bo jak dla mnie to JPA/Hibernate to g**no.. (no jakiś komunikat o problemie by się przydał, bo śledzenie po wszystkich powiązaniach, co do cholery trzymie obiekt podczas flush to niezła bryndza).


jeden i pół terabajta powinno wystarczyć każdemu
edytowany 4x, ostatnio: jarekr000000
RezyserKinaAkcji
  • Rejestracja:prawie 5 lat
  • Ostatnio:około 2 lata
  • Postów:163
0

@jarekr000000: Dzięki wielkie. Działa. Tylko tutaj teraz pojawia się problem, ze kasowanie Usera kasuje również rekord w tabeli ActivationCode, a tego chciałem uniknąć. Chciałem, by kasowanie Usera zwalniało ActivationCode, który później można by przypisać innemu Userowi, a nie kasowało go całkowicie.

Tak czy siak to kosmetyka i da się z tym żyć :P Dzięki wielkie za znalezienie rozwiązania !

jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około godziny
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4707
1

To przed remove(user) ustaw user = null na tym ActivationCode i powinno być ok.


jeden i pół terabajta powinno wystarczyć każdemu
edytowany 2x, ostatnio: jarekr000000
RezyserKinaAkcji
  • Rejestracja:prawie 5 lat
  • Ostatnio:około 2 lata
  • Postów:163
1

@jarekr000000: Ahh, no tak. Chyba nawet tak to było rozwiązane na kursie. No jasne. Dzięki wielkie. I swoją drogą pozdrawiam Pana Czarodzieja, po którego rekomendacjach trafiłem na to zacne forum ;)

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.