2012-10-24 151 views
8

我有2類:用戶和UserPicture有1:1的關係。休眠 - 雙向@OneToOne

public class User { 
    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    @Column(name="id", nullable = false, unique = true) 
private int id; 

    private String firstname; 

    private String lastname; 

    @OneToOne 
    @JoinColumn(name = "picture") //field named "picture" in the database 
    private UserPicture userPicture; 

    .. 
} 


public class UserPicture { 

    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    @Column(name="id", nullable = false, unique = true) 
    private int id; 

    private Blob image; 

    @OneToOne 
    @JoinColumn(name = "user") 
    User user; 

在UserPicture「用戶」將被載入但在用戶「userPicture」不 - 你說我錯了?

編輯 要補充一句,我只是創造一個UserPicture和插入(與現有的用戶id) - 也許我需要級聯「用戶」在UserPicture?

回答

14

你必須映射你的類。

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

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

它的工作原理!謝謝!但是,如果我插入一個UserPicture用戶不會被更新? – user1731299

+0

@ user1731299爲了將'User'與'UserPicture'關聯起來,所有必須做的事情就是創建一個'UserPicture',在對象上調用'setUser'並將其保存在數據庫中。 – Pigueiras

+0

以下內容:前端請求我向用戶A添加用戶圖片。在我的服務中,我重新加載用戶A,將此用戶設置爲新的UserPicture對象,並在表user中創建/插入UserPicture - >字段'picture'。如果我正在加載用戶,現場圖片加載..真是奇怪。 – user1731299

2

在問候你的問題!(因爲我沒有足夠的信譽評論做出迴應)

「全部清除只有一個問題多,是有可能使userPicture用戶偷懶? - - user1731299 10年12月24日在10:44「

是的,它是可能的,使其懶惰獲取。但是,只是說「fetchType = FetchType.Lazy」將不起作用。原因在於,Hibernate需要檢查連接的表以查看它是否爲空值,或者是否存在記錄。由於它是OneToOne映射,因此Hibernate認爲它可以通過撤回那裏的任何數據來保存數據庫調用,因爲它必須檢查它是否爲空。對於x對多映射,情況並非如此,因爲Hibernate知道'many'意味着在另一個表上有一個列表正在等待......無論是一個空列表還是一個填充列表,它仍然是一個列表。對於單個值,它必須區分實際數據和空值。

解決這個問題的方法是告訴Hibernate,總會有一個值,永遠不會有空值。瞭解這一點,Hibernate可以創建一個佔位符,直到需要獲取數據爲止。您在批註中執行此操作的方式是將「optional = false」添加到@OneToOne批註中。

但請注意!這有一些問題;包括我現在想弄明白的那個(以及我在這裏遇到的問題)。這個可選= false使得Hibernate做了一些額外的驗證,並且似乎混淆了Hibernate應該如何執行插入操作。所以,你可能想要遠離這種懶惰的抓取技術。

1

即使我們在JoinColumn註釋中將字段指定爲非空值,One to One中的延遲加載也可以工作。然而,在雙向One to One中,延遲加載對我們使用mappedBy =''的實體不起作用。例如,如果我們有兩個實體Contract和House,其中Contract窗口擁有House的外鍵。當我們在這裏使用雙向OneToOne並嘗試加載合同,然後延遲加載工作(即House沒有急切加載),但是當我們嘗試加載House(使用House存儲庫)時,合約總是被熱切地提取。有人知道爲什麼會發生這種情況嗎?

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

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

我知道這只是一個部分答案,暨問題。但這與這裏的討論非常相關。