具有共享主键和子端@OneToOne 的单向一对一关系

Unidirectional one-to-one relationship with shared primary key and @OneToOne on child side

我有一个 Appliance 实体如下:

public class Appliance {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;

    // other appliance fields
 }

然后我有另一个 class 用于将第三方设备映射到设备:

public class ThirdPartyApplianceMapping {

    @Id
    private Long applianceId;

    private Long thirdPartyApplianceId;

    @OneToOne
    @JoinColumn(name="applianceId", nullable=false)
    private Appliance appliance;

 }

我希望数据库的结构如下:

Appliance(
     id PK,
     -- other columns but no col reference to ThirdPartyApplianceMapping
)

ThirdPartyApplianceMapping(
     applianceId PK FK references Appliance.id,
     thirdPartyApplianceId
)

如何定义/注释我的实体,使 ThirdPartyApplianceMapping.applianceId 是 PK,FK 回到 Appliance.idAppliance 一定不知道 ThirdPartyApplianceMapping。我正在使用 Hibernate 的 JPA 2 实现。

The @Id annotation or id XML attribute can be added to a OneToOne or ManyToOne mapping. The Id used for the object will be derived from the target object's Id. If the Id is a single value, then the source object's Id is the same as the target object's Id.

来源:wikibooks

所以对于你的情况,应该这样做:

public class ThirdPartyApplianceMapping {

    private Long thirdPartyApplianceId;

    @Id
    @OneToOne
    @JoinColumn(name="applianceId", nullable=false)
    private Appliance appliance;

}

这可以在 MapsId 的帮助下完成:

Designates a ManyToOne or OneToOne relationship attribute that provides the mapping for an EmbeddedId primary key, an attribute within an EmbeddedId primary key, or a simple primary key of the parent entity.

在这种情况下 appliance 应该用 MapsId 注释:

@OneToOne
@JoinColumn(name="applianceId")
@MapsId
private Appliance appliance;

也删除了 nullable=false,因为根据定义,主键不可为空。