2012-10-24 18 views
8

Mam 2 klasy: User i UserPicture, które mają związek 1: 1.Hibernate - dwukierunkowy @OneToOne

"Użytkownik" w UserPicture zostanie załadowany, ale "userPicture" w User not - what Did Im wrong?

EDIT trzeba dodawać, że jestem po prostu stworzyć obrazka użytkownika i wstawić je (z istniejących userid) - może muszę kaskadowo „użytkownik” w obrazka użytkownika?

Odpowiedz

14

Musisz mapować swoje zajęcia.

public class User { 
    ... 
    @OneToOne (mappedBy="user") 
    private UserPicture userPicture; 
    ... 
} 

public class UserPicture { 
    ... 
    @OneToOne 
    @JoinColumn (name="user") 
    private User user; 
    ... 
} 
+0

Działa! Dzięki! Ale czy mogę wstawić użytkownika UserPicture użytkownika nie będzie aktualizowany? – user1731299

+0

@ user1731299 Wszystkie rzeczy, które musisz zrobić, aby powiązać 'użytkownika' z' UserPicture', to stworzyć 'UserPicture', wywołać' setUser' na obiekcie i utrzymywać go w DB. – Pigueiras

+0

Poniżej: Frontend poprosił o dodanie obrazu użytkownika do użytkownika A. W mojej usłudze przeładowuję użytkownika A, ustawę tego użytkownika na mój nowy obiekt UserPicture i utworzę/wstawię UserPicture -> pole 'picture' w tabeli user stay stay null. Jeśli im załaduję użytkownika, obraz pola zostanie załadowany .. naprawdę dziwny. – user1731299

2

W odniesieniu do Twojego pytania: (bo nie mam wystarczająco dużo reputacji, aby odpowiedzieć w komentarzu)

„Wszystko jasne, tylko jedno pytanie więcej, jest to możliwe, aby obrazka użytkownika w Użytkownik leniwe ? - user1731299 Październik 24 '12 at 10:44 "

Tak, to jest możliwe, aby to leniwy aport. Jednak samo powiedzenie "fetchType = FetchType.Lazy" nie będzie działać. Powodem jest, że Hibernate musi sprawdzić połączoną tabelę, aby sprawdzić, czy jest to wartość pusta, czy jest tam zapis. Ponieważ jest to mapowanie OneToOne, Hibernate rysuje, że może zapisać wywołanie bazy danych, po prostu wycofując wszelkie dane, które tam są, ponieważ musiał sprawdzić, czy i tak był pusty. Nie jest tak w przypadku odwzorowań x-do-wielu, ponieważ Hibernate wie, że "wiele" oznacza, że ​​na drugiej tabeli czeka lista ... pusta lub zapełniona lista, to wciąż lista. Dla pojedynczej wartości musi odróżniać rzeczywiste dane od wartości pustej.

Sposób obejścia tego polega na przekazaniu Hibernate, że ZAWSZE będzie tam wartością i NIGDY nie będzie wartością pustą. Wiedząc o tym, Hibernate może stworzyć miejsce pobytu aż do czasu, aby pobrać te dane. Sposób w adnotacjach polega na dodaniu "optional = false" do adnotacji @OneToOne.

Należy jednak zachować ostrożność! Jest w tym kilka problemów; w tym ten, który próbuję rozgryźć teraz (i jak natknąłem się na twoje pytanie tutaj). Opcjonalny = false sprawia, że ​​Hibernate robi trochę dodatkowej weryfikacji i wydaje się mylić Hibernate z tym, jak powinien wykonywać wstawki. Więc możesz chcieć trzymać się z dala od tej leniwej techniki pobierania.

1

Leniwe ładowanie w trybie One to One działa nawet wtedy, gdy w adnotacji JoinColumn określamy pole jako non-nullable. Jednak w dwukierunkowym One-One leniwy ładowanie nie działa na obiekcie, w którym używamy mappedBy = ''. Na przykład, jeśli mamy dwa podmioty: kontrakt i dom, gdzie tabela kontraktów zawiera klucz obcy dla domu. Kiedy używamy tutaj dwukierunkowego OneToOne i próbujemy wczytać kontrakt, to leniwe prace ładunkowe (tj. House nie jest ładowany z zapałem), ale kiedy próbujemy załadować House'a (używając repozytorium House'a), kontrakt jest zawsze pobierany z niecierpliwością. Czy ktoś ma pomysł, dlaczego tak się dzieje?

Public class Contract { 
    ..... 
    @onetoone(lazy) 
    @JoinColumn(name='houseid', nullable=false) 
    Private House house 
    ..... 
} 

Public class House { 
    ..... 
    @onetoone(lazy, mappedBy='house') 
    Private Contract contract 
    ..... 
} 

Wiem, że to tylko częściowa odpowiedź, cum pytanie. Ale jest to bardzo związane z dyskusją tutaj.

Powiązane problemy