简体   繁体   English

JPA 2:通过查找JoinColumn-一对一关系中的共享主键来确定实体ID

[英]JPA 2: Determine an entitys id by looking up JoinColumn - Shared primary key in one-to-one relation

I have two entity classes Client and Preferences in a bidirectional one-to-one relation. 我在双向一对一关系中有两个实体类Client和Preferences。 The entities should share the same primary key, which is generated programmatically by java.util.UUID. 实体应该共享相同的主键,该主键由java.util.UUID以编程方式生成。

Here is the minimalistic scenario: 这是简约方案:

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

    // ...
}

Everything works fine but I am disaffected because I can't find a clean way to provide a simple id field/property in Preferences. 一切正常,但是我不满意,因为我找不到在“首选项”中提供简单id字段/属性的干净方法。

In the scenario above I am forced to determine it by calling client.getId(); 在上述情况下,我不得不通过调用client.getId();来确定它client.getId(); all the time which looks quite messed up. 所有的时间看起来都很混乱。 So I was trying to figure out some alternatives. 因此,我试图找出一些替代方案。 Here is what I found out so far: 这是我到目前为止发现的:

Alternative A: Persist a basic value called id: 备选方案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();
    }

    // ...
}

The main problem with that solution is that it would store the same value twice...why then share a pk at all?! 该解决方案的主要问题是它将存储相同的值两次...为什么要共享一个pk?

Alternative B: Transient id: 备选方案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();
    }

    // ...
}

Okay, here we don't save redundant data but Client must be fetched eagerly erverytime. 好的,这里我们不会保存冗余数据,但是必须总是急切地获取客户端。 That's the default behaviour in one-to-one relations but what if it would be better someday to have that client being fetched lazily? 这是一对一关系中的默认行为,但是如果有一天最好让那个客户懒洋洋地拿来更好呢? I don't like my options being restricted for no reason. 我不喜欢无故限制我的选择。

Is there a way to read the id given by Client directly out of that JoinColumn or should I use solution A/B? 有没有一种方法可以直接从JoinColumn中读取客户提供的ID,还是应该使用解决方案A / B?

I'm trying to stick to the spec, provider independent hints would be nice. 我正在尝试遵守规范,提供程序独立提示会很好。

Thank you! 谢谢!

Give this a try. 试试看。 It should grab the ID from the Client. 它应该从客户端获取ID。

@Entity
public class Preferences implements Serializable {

@Id String id;

  @OneToOne @MapsId
  @JoinColumn
  private Client client;

}

// ...

} }

Furthermore, it might be worthwhile understanding which Object owns the relationship. 此外,可能值得了解哪个对象拥有该关系。 It appears from your design that Preferences owns Client as Client (the non-owning side contains the mappedBy). 从您的设计中可以看出,“首选项”将“客户端”作为“客户端”拥有(非所有者端包含“ mappedBy”)。 Therefore it might be true in this case that the MapsId annotation is best suited to the non-owning (dependent object). 因此,在这种情况下,MapsId注释最适合非所有者(从属对象)可能是正确的。 Eg Add MapsId to the Client not Preferences as above. 例如,将MapsId添加到客户端,而不是如上所述的“偏好设置”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM