OneToOne双向映射外键自动填充



我在两个表之间有一个一对一的关系,但是外键在我不需要映射的表上,DBA这样做是为了方便将来的更改。

让我们假设我们有User和Address,今天每个用户只有一个地址,它将以这种方式映射,但DBA相信将来它可能是一对多的映射,所以User的外键在地址上,但应用程序有用户的实例,这对自动获取地址很重要。

我们做对了,如下:

@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足够聪明,设置它的值从用户的实例,它来自。

我一直在寻找一个解决方案几天,但仍然没有找到如何解决这个问题,同时我手动设置值,但我希望我不需要这样做。

标准的解决方案是正确地更新双向关联的双方(尽管只有拥有方需要更新,以便将关联保存到数据库中)。UserAddress setter添加:

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);

如果不需要"private User User ",则删除它并删除'User'实体中的also mappedBy。使用单向关系

在你的例子中,mappedBy意味着关联的所有者是"Address"实体,所以保存Address而不是User的实例。例如:

adress.setUser(user);
session.save(adress);

您需要添加CasecadeType。PERSIST使创建地址与创建User同步。

在您的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代码,并给出你期望的详细描述。

相关内容

  • 没有找到相关文章

最新更新