[英]OneToOne bidirectional mapping foreign key auto fill
我在兩個表之間是一對一的關系,但是外鍵位於我不需要映射的表上,DBA這樣做是為了將來的更改。
假設我們有用戶和地址,今天每個用戶只有一個地址,並且將以這種方式進行映射,但是DBA相信將來它可能是一對多的映射,因此用戶的外鍵在地址上,但是應用程序具有用戶實例,這對於自動獲取地址很重要。
我們做對了,如下所示:
@Entity
@Table(name = "user")
class User {
@Id
@Column(name = "user_id")
private Long id;
//...
@OneToOne(cascade = CascadeType.MERGE, mappedBy = "user")
private Address address; // this attribute is crucial
}
@Entity
@Table(name = "address")
class Address {
@Id
@Column(name = "address_id")
private Long id;
@OneToOne
@JoinColumn(name = "user_id")
private User user; // this attribute is not needed for the business at all, but mappedBy requires it
//...
}
數據庫:
-- SQL:
CREATE TABLE user
(
user_id INT NOT NULL,
-- ...
CONSTRAINT user_pk PRIMARY KEY (user_id)
);
CREATE TABLE address
(
address_id INT NOT NULL,
user_id INT NOT NULL,
-- ...
CONSTRAINT address_pk PRIMARY KEY (address_id),
CONSTRAINT address_user_id_fk FOREIGN KEY (user_id) REFERENCES user (user_id),
CONSTRAINT address_user_id_uk UNIQUE (user_id) -- it says it's a one to one relation for now, if in the future it won't be anymore, just remove this constraint
);
問題是當用新的地址實例保存用戶實例時,該用戶的地址屬性為null
,因此我期望Hibernate足夠聰明,可以根據來自它的用戶實例為其設置值。
我一直在尋找解決方案幾天,但仍然找不到解決方法,與此同時,我正在手動設置該值,但是我希望不需要這樣做。
標准解決方案是正確地更新雙向關聯的兩端(盡管僅需要更新擁有端才能將關聯保存到數據庫中)。 在User
類中添加到Address
設置器:
public void setAddress(Address address) {
this.address = address;
address.setUser(this);
}
另外,您可能希望擴展address
屬性的級聯選項以使其也包括PERSIST
,以便始終將其與其用戶保持在一起:
@OneToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, mappedBy = "user")
private Address address;
然后,您可以為用戶設置地址,並同時保留兩個地址:
user.setAddress(address);
session.persist(user);
如果不需要“私人用戶”,則將其刪除,並同時刪除“用戶”實體中的mappedBy。 使用單向關系。
在您的示例中,mappedBy表示關聯的所有者是“地址”實體,因此請保存Adress實例而不是User。 喜歡 :
adress.setUser(user);
session.save(adress);
您需要添加CasecadeType.PERSIST來創建帶有用戶創建的地址案例。
在您的Java代碼中,您需要執行以下操作:
user.setAddress(address);
address.setUser(user);
session.persist(user);
然后,將為您的用戶創建一個地址。
如果僅當您想要讀取新創建的用戶的地址時,則需要執行以下操作:
// your code to persist a new User and Address
session.flush();
session.refresh(user);
如果不是您想要的,那么您需要共享自己的Java代碼,並詳細說明您的期望。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.