2012-10-08 17 views
5

Mam relację wiele do wielu, gdy tabela linków ma dodatkowe pole. Stąd związku odbywa się za pomocą 2 jeden do licznych związków według poniższej artykule:Hibernacja: łączenie z wieloma do wielu wyników w StackOverflowError

http://www.mkyong.com/hibernate/hibernate-many-to-many-example-join-table-extra-column-annotation/comment-page-1/#comment-122181

mam 2 podmioty, do trzeciej jednostki, które określa tabeli łączy i składa się z @Embeddable polu ID.

Zależność jest zdefiniowany jako:

@OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.compound", cascade = CascadeType.ALL) 

@OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.structure", cascade = CascadeType.ALL) 

były PK = pole ID @Embeddable. Wstawianie i usuwanie działa dobrze jednak gdy zgłoszę

session.merge(compound); 

dostaję StackOverflowError i pokazuje, że hibernacja jest uczynienie ton wybranych sprawozdań zalogować. Zauważ, że baza danych zawiera dokładnie 1 powiązanie, np. 1 związek zawierający 2 struktury. Wygląda na to, że hibernacja wchodzi w nieskończoną pętlę.

Widziałem to rozwiązanie również na http://giannigar.wordpress.com/2009/09/04/mapping-a-many-to-many-join-table-with-extra-column-using-jpa/, ale w jaki sposób można to zaktualizować?

+2

Być może ładujesz swoje pełne tabele wielu do wielu za pośrednictwem relacji wiele do wielu. Wyobraź sobie "A1" odwołujące się do "B1". "B1" odnosi się do "A1" i "A2". "A2" odnosi się do "B2". I tak dalej. Przy każdym przełączeniu z jednej strony relacji na drugą uzyskujesz dodatkowy poziom stosu. – SpaceTrucker

+0

Trwałość i ładowanie działają, ale podczas wywoływania scalania pojawia się problem. –

+0

@SpaceTrucker, jednak scalanie powinno zarządzać obiektami odwiedzanymi przez podoperację wcześniejszego scalania. beginner_ możesz udostępnić swoje pełne jednostki w teście, abyśmy mogli lepiej Ci pomóc. –

Odpowiedz

3

Moim rozwiązaniem było użycie FetctType.EAGER po stronie posiadania i FetchType.Lazy na stronie dziecięcej oraz w 2 relacjach ManyToOne w tabeli linków. W ten sposób mogę załadować od strony właściciela bez uzyskania LazyInitializationException i scalania działa zgodnie z oczekiwaniami.

0

I druga odpowiedź SpaceTuckkera. Nie sądzę, żeby Persist był tym samym, co połączenie. Merge załaduje obiekt przed jego utrwaleniem. Persist nie. Tak więc, gdy wywołujecie połączenie IMHO, trzeba wczytać relację leniwą. Jeśli wywołasz persist, nie działa.

Możesz również użyć @ElementDependent, aby oznaczyć powiązane relacje @OneToMany jako zależne od innej tabeli. W ten sposób rozwiązałem relację wiele do wielu z dodatkowymi kolumnami w tabeli sprzężenia.

+2

Tak, ale uzyskanie podmiot działa. Mogę więc przetrwać iw zupełnie innej sesji załadować go i bez problemu. Problem występuje tylko podczas scalania. Rozwiązaniem okazało się dodanie fetch = FetchType.LAZY do relacji ManyToOne w klasie Embeddable ID. –

Powiązane problemy