簡體   English   中英

OneToOne雙向映射外鍵自動填充

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM