1

我在双向一对一关系中有两个实体类 Client 和 Preferences。实体应共享相同的主键,该主键由 java.util.UUID 以编程方式生成。

这是简约的场景:

@Entity
public class Client implements Serializable {

    @Id
    private String id;

    @OneToOne(mappedBy = "client", casacade = CascadeType.PERSIST)
    private Preferences preferences;

    // ...
}

@Entity
public class Preferences implements Serializable {

    @Id
    @OneToOne
    @JoinColumn
    private Client client;        

    // ...
}

一切正常,但我不满意,因为我找不到在首选项中提供简单 id 字段/属性的干净方法。

在上面的场景中,我被迫通过一直调用来确定它,client.getId();这看起来很混乱。所以我试图找出一些替代方案。这是我到目前为止发现的:

备选方案 A:保留一个名为 id 的基本值:

@Entity
public class Preferences implements Serializable {

    @Id
    @OneToOne
    @JoinColumn
    private Client client;

    private String id;

    public setClient (Client client) {
        this.client = client;
        id = client.getId();
    }

    // ...
}

该解决方案的主要问题是它会两次存储相同的值......为什么还要共享一个pk?!

备选方案 B:瞬态 ID:

@Entity
public class Preferences implements Serializable {

    @Id
    @OneToOne
    @JoinColumn
    private Client client;

    @Transient
    private String id;

    @PostLoad
    private void postLoad () {
        id = client.getId();
    }

    public setClient (Client client) {
        this.client = client;
        id = client.getId();
    }

    // ...
}

好的,这里我们不保存冗余数据,但必须每次都急切地获取客户端。这是一对一关系中的默认行为,但如果有一天延迟获取该客户端会更好呢?我不喜欢我的选择无缘无故地受到限制。

有没有办法直接从 JoinColumn 中读取 Client 给出的 id 或者我应该使用解决方案 A/B?

我正在尝试遵守规范,提供者独立的提示会很好。

谢谢!

4

1 回答 1

1

试试这个。它应该从客户端获取 ID。

@Entity
public class Preferences implements Serializable {

@Id String id;

  @OneToOne @MapsId
  @JoinColumn
  private Client client;

}

// ...

}

此外,了解哪个 Object 拥有该关系可能是值得的。从您的设计中可以看出,Preferences 将 Client 作为 Client 拥有(非拥有方包含 mappedBy)。因此,在这种情况下,MapsId 注释最适合非拥有(依赖对象)可能是正确的。例如,将 MapsId 添加到客户端而不是上面的首选项。

于 2013-10-09T22:46:34.607 回答