2017-05-14 50 views
1

我想User.idAddress.user_idJPA:OneToOne關係所有者

使2款之間的關係

創建兩個表一比一的關係:

@Entity() 
@Table(name = "user") 
public class User { 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Integer id; 

    @OneToOne(cascade = CascadeType.ALL) 
    @JoinColumn(name = "id", referencedColumnName = "user_id") 
    private Address address; 

    public int getId() { 
     return id; 
    } 

    public void setId(Integer id) { 
     this.id = id; 
    } 

    public Address getAddress() { 
     return address; 
    } 

    public void setAddress(Address address) { 
     this.address = address; 
    } 

} 



@Entity 
@Table(name = "address") 
public class Address extends com.mezoline.domain.common.Entity { 

    @Id 
    @GeneratedValue 
    private int id; 

    @OneToOne(mappedBy = "address") 
    private User user; 

    public int getId() { 
     return id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

    public User getUser() { 
     return user; 
    } 

    public void setUser(User user) { 
     this.user = user; 
    } 

} 

在這裏,我已經可以看到問題:hibernate沒有生成數據庫列Address.user_id我的預期如何。

創建Address實例,並添加到User

User user = entityManager.find(User.class, 69); 
    Address address = new Address(); 
    address.setCity("Тест"); 
    userTransaction.begin(); 
    user.setAddress(address); 
    entityManager.merge(user); 
    userTransaction.commit(); 

我打電話merge(user)後。數據成功保存...沒有任何關係信息。

UPD:

下面的配置,JPA將創建關係列Address.user_id(只是老闆的關係被交換)

public class User { 
    ... 
    @OneToOne(cascade = CascadeType.ALL, mappedBy = "user") 
    private Address address; 
    ... 
} 

public class Address { 
    .... 
    @OneToOne() 
    @JoinColumn(name = "user_id") 
    private User user; 
    .... 
} 

但後保存Address.user_id爲空...(其它列正在填充)

UPD2:

謝謝。其次配置做工精細,當設置反方關係領域(如評論建議):

Address address = createAddress(); 
address.setUser(user); 
user.setAddress(address); 

但我不`噸明白,爲什麼第一個配置(用戶是擁有方)唐不工作。

回答

2

這是因爲您對初始配置的期望有邏輯錯誤。

您聲明User擁有一方的關係。 擁有表示表示該關係的外鍵將保留在USER表中,而不保留在Address表中。

與此同時,您註釋了User.address@JoinColumn(name = "id", referencedColumnName = "user_id")。基本上,我認爲你試圖強制ADRESS表保存外鍵。但在這種情況下,Adress應該是擁有方

如果你想要初始配置工作,你應該做的就是你應該用@JoinColumn(name = "address_id")替換當前的JoinColumn註釋。外鍵將在USER表中結束。當堅持實體時,必須設置User.address;設置Address.user是可選的。

如果你絕對必須的ADDRESS表中的鍵,使Address臺擁有方(那麼你只需要確保Address.user設定在持續時間;但是,你還是會希望User.address被設置以便級聯工作,除非明確堅持Address實體)。

1

因爲它是雙向One-to-One,還需要持續的父/超級實體之前設置反側所謂的母公司。

Address addr = new Address() 
user.setAddress(addr); 
addr.setUser(user); 
session.save(user); 
+0

嗯..謝謝。我認爲JPA管理自己..(AOP) – Hett

1

我會留在原配置,用戶是擁有的一方。對於我來說,對你的模式更有意義。

關於Address上的user_id列..您必須確保在關係的兩側都設置了依賴關係。所以你的transanctional方法應該包含以下內容:

if (user.getAddress() == null) { 
    Address address = createAddress(); 
    address.setUser(user); 
    user.setAddress(address);   
} 
+0

第一次配置休眠不創建列Address.user_id .. – Hett