OneToMany/ ManyToOne - usuwanie - Hibernate

OneToMany/ ManyToOne - usuwanie - Hibernate
P7
  • Rejestracja:około 8 lat
  • Ostatnio:ponad 7 lat
  • Postów:11
0

Witam. W aplikacji mam kilka klas encji. dwie z nich polaczylem OneToMany/ ManyToOne. wyglada to mniejwiecje tak:
Club:

Kopiuj
@OneToMany(mappedBy = "playersClub",
        orphanRemoval = true
)
@Cascade({CascadeType.ALL})
@ContainedIn
private Set<Player> players;

oraz Player:
..

Kopiuj
    @ManyToOne
//        (
//            fetch = FetchType.EAGER
//    )
    @Cascade({org.hibernate.annotations.CascadeType.ALL})
    @IndexedEmbedded(depth = 1)
    private Club playersClub;

Chciałbym aby po usunięciu silniejszej encji(tutaj Club) usuwały sie rownież slabsze encje(Players). probowałem roznych kombinacji z adnotacja @OnDelete, orphanDelete, cascade z Hibernate i JPA i chyba sie pogubiłem, bo niestety nic nie działa, czy ktoś mógłby mnie naprowadzić na poprawny tor?

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

A gdzie w ogóle masz ustawione klucze obce?


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
P7
  • Rejestracja:około 8 lat
  • Ostatnio:ponad 7 lat
  • Postów:11
0

no klucze obce znajdują sie w tabeli players

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

Ale nie chodzi o tabele bazodanowe tylko o mapowanie w ORM


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
P7
  • Rejestracja:około 8 lat
  • Ostatnio:ponad 7 lat
  • Postów:11
0

wybacz ale chyba nie rozumiem?
Relacja odpowiada na za zmapowanie kluczy obcych

edytowany 1x, ostatnio: proceder7
S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:6 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
0

Chodzi o JoinColumn. Skąd ma hibernate wiedziec że to jest klucz obcy jak mu nie powiesz?


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
P7
  • Rejestracja:około 8 lat
  • Ostatnio:ponad 7 lat
  • Postów:11
0

jest to automatycznie dodawane na zasadzie nazwapola_id. a za samo mapowanie odpowiada mappedBy.

edytowany 1x, ostatnio: proceder7
S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:6 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
0

Jeszcze nie widziałem żeby było mapowanie takie bez @JoinColumn
Niech się @Shalom albo @Koziołek wypowiedzą :)


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
Koziołek
wystarczy, że masz mappedBy w encji, która trzyma kolekcję.
S9
@Koziołek: a skąd będzie Hibernate wiedział że taki jest klucz obcy?
Koziołek
W tabeli, Player w tym przypadku, będzie kolumna Club z FK.
P7
  • Rejestracja:około 8 lat
  • Ostatnio:ponad 7 lat
  • Postów:11
0

dodanie JoinColumn nic nie zmienia. te same bledy.

Kopiuj
 Cannot delete or update a parent row: a foreign key constraint fails (`portalstat`.`player`, CONSTRAINT `FK8EA38701C3272131` FOREIGN KEY (`id_klubu`) REFERENCES `club` (`id`))
Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
1
  1. Nie mieszaj typow z JPA z tymi z Hibernate! One sie moga nazywac tak samo, ale nie beda razem dzialac!
  2. CascadeType.ALL z JPA po stronie one powinno zalatwic sprawe o ile dobrze rozumiem co robisz.

"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:6 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
0

Masz jakiś DDL do tej bazy danych? :)
Edit a no właśnie, może mieszasz adnotacje JPA i Hibernate


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
edytowany 1x, ostatnio: scibi92
P7
  • Rejestracja:około 8 lat
  • Ostatnio:ponad 7 lat
  • Postów:11
0

no wlasnie w tym rzecz, ze to nie dziala:
Club:

Kopiuj
    @OneToMany(mappedBy = "playersClub"
            ,cascade = javax.persistence.CascadeType.ALL
    )
    private Set<Player> players;

Player:

Kopiuj
    @ManyToOne
    private Club playersClub;
S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:6 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
0

Masz ten błąd SQLowy?


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
P7
  • Rejestracja:około 8 lat
  • Ostatnio:ponad 7 lat
  • Postów:11
0

tak, wyskakuje gdy chce usunać Club ktory posiada Playera.

Kopiuj
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`portalstat`.`player`, CONSTRAINT `FK8EA38701D5EDDE20` FOREIGN KEY (`playersClub_id`) REFERENCES `club` (`id`))
Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

aa no ale ty to robisz odwrotnie zupelnie. Jesli robisz mappedBy = "playersClub" to wlascicielem tego powiazania jest playersClub!
http://stackoverflow.com/questions/7197181/jpa-unidirectional-many-to-one-and-cascading-delete


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
0

Taki przykładzik znalazłem w sieci, trochę rozdmuchana konfiguracja ale może pomoże w tym wypadku.

Parent
.......
@OneToMany (mappedBy = "parent", orphanRemoval = true, cascade={CascadeType.ALL}, targetEntity = Children.class)
private List <Children> children;
.........

Children
......
@ManyToOne(targetEntity = Parent.class, cascade = CascadeType.ALL)
@JoinColumn(name = "parent_id")
private Parent parent;

P7
  • Rejestracja:około 8 lat
  • Ostatnio:ponad 7 lat
  • Postów:11
0

@up z tym nie ma błędu ale tutaj chodzi o to, że w obu relacjach jest cascadeType.all. teraz wyglada to u mnie tak:
Club:

Kopiuj
    @OneToMany(mappedBy = "playersClub"
            ,orphanRemoval = true
            ,cascade = javax.persistence.CascadeType.ALL
//            ,targetEntity = Player.class
    )
    private Set<Player> players;

Player:

Kopiuj
    @ManyToOne(
//            targetEntity = Club.class,
            cascade = CascadeType.ALL)
    @JoinColumn(name = "id_klubu")
    private Club playersClub;

I gdy wciskam przycisk usun Club strona sie odswieza i nic z tego nie przychodzi. Wcisniecie przycisku gdy nie ma player's powoduje poprawne usuniecie.

@Shalom
nie bardzo rozumiem co masz na myśli? zawsze w mappedBy dawalem to co jest po drugiej stronie relacji

P7
a powinno? bo nie duzo to zmienia dla mnie :(
S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:6 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
0

Nie no to źle, tak nie powinno być że w obu relacjach jest Cascade.ALL
Powinna być tylko po stronie rodzica jak już :)


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
P7
  • Rejestracja:około 8 lat
  • Ostatnio:ponad 7 lat
  • Postów:11
0

no to pisalem juz, ze jak nie ma cascadeType.ALL w obu stronach to jest blad "Cannot delete or update a parent row: a foreign key constraint fails"

hmm.. moze rozwine problem, bo wlasnie zdalem sobie sprawę, że wina nie leży po stronie relacji, ani DB.
Otoz aplikacja pisana jest w JSF2. Gdy Dodam klub i zawodników do niego i chce usunąć dany klub mam w/w blad. jesli są cascadeType.ALL po obu stronach - nic sie nie dzieje.
Natomiast gdy wylacze server i wlacze aplikację ponownie to mogę usunąć ten klub a wraz z nim usuwają się zawodnicy - czyli działa. kwestia pewnie w Hibernate - uzywam entityManagera, ale nigdzie go nie zamykam. To jest funkcja zapisująca encję w DB.

Kopiuj
    public void createPlayer(Player player) {
        entityManager.getTransaction().begin();
        entityManager.persist(player);
        entityManager.getTransaction().commit();
    }

podobnie klub.

powinienem za kazdym razem tworzyc nowy entityManager i go zamykac?

edytowany 1x, ostatnio: proceder7

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.