具有共享ID的JPA @OneToOne - 我可以做得更好吗? [英] JPA @OneToOne with Shared ID -- Can I do this Better?

查看:141
本文介绍了具有共享ID的JPA @OneToOne - 我可以做得更好吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用现有的架构,我宁愿不改变。表格Person和VitalStats之间具有一对一的关系,其中Person具有主键,VitalStats使用与其主键相同的字段及其对Person的外键,这意味着其值是相应PK的值of person。

I’m working with an existing schema that I’d rather not change. The schema has a one-to-one relationship between tables Person and VitalStats, where Person has a primary key and VitalStats uses the same field as both its primary key and its foreign key to Person, meaning its value is the value of the corresponding PK of Person.

这些记录是由外部进程创建的,我的JPA代码永远不需要更新VitalStats。
对于我的对象模型,我希望我的Person类包含一个VitalStats成员,但是:

These records are created by external processes, and my JPA code never needs to update VitalStats. For my object model I’d like my Person class to contain a VitalStats member, BUT:

当我尝试

@Entity
public class Person{
    private long id;
    @Id
    public long getId(){ return id; }

    private VitalStats vs;
    @OneToOne(mappedBy = "person")
    public VitalStats getVs() { return vs; }
}

@Entity
    public class VitalStats{
     private Person person;
    @OneToOne
    public Person getPerson() { return person; }
}

我遇到的问题是VitalStats缺少@Id,而不是工作@ Entity.\

I have the problem that VitalStats lacks an @Id, which doesn’t work for an @Entity.\

如果我尝试

@Id @OneToOne
public Person getPerson() { return person; }

解决了@Id问题,但要求Person可序列化。我们将回到那里。

that solves the @Id problem but requires that Person be Serializable. We’ll get back to that.

我可以制作VitalStats @Embeddable并通过@ElementCollection将其连接到Person,但是它必须作为集合访问即使我知道只有一个元素。可行,但有点烦人,有点令人困惑。

I could make VitalStats @Embeddable and connect it to Person via an @ElementCollection, but then it would have to be accessed as a collection, even though I know that there’s only one element. Doable, but both a little bit annoying and a little bit confusing.

那么是什么阻止我只是说Person实现了Serializable?没什么,真的,除了我喜欢我的代码中的所有东西都存在,并且我看不到任何逻辑,这使得我的代码更不易读。

So what’s preventing me from just saying that Person implements Serializable? Nothing, really, except that I like everything in my code to be there for a reason, and I can’t see any logic to this, which makes my code less readable.

与此同时,我刚刚用一个很长的人替换了VitalStats中的Person字段并制作了VitalStats的@Id,所以现在@OneToOne正常工作。

In the meantime I just replaced the Person field in VitalStats with a long personId and made that VitalStats’s @Id, so now the @OneToOne works.

所有这些解决方案似乎(对我而言)像一个简单的问题有点笨重,所以我想知道我是否遗漏了任何东西,或者是否有人至少可以向我解释为什么人必须是可序列化的。

All of these solutions to what seems (to me) like a straightforward issue are a bit clunky, so I’m wondering whether I’m missing anything, or whether someone can at least explain to me why Person has to be Serializable.

TIA

推荐答案

要使用共享主键映射一对一关联,请使用 @PrimaryKeyJoinColumn @MapsId 注释。

To map one-to-one association using shared primary keys use @PrimaryKeyJoinColumn and @MapsId annotation.

相关部分Hibernate参考文档:

Relevant sections of the Hibernate Reference Documentation:

PrimaryK eyJoinColumn


PrimaryKeyJoinColumn注释确实说实体的
主键用作外键值到关联实体。

The PrimaryKeyJoinColumn annotation does say that the primary key of the entity is used as the foreign key value to the associated entity.

MapsId


MapsId注释问Hibernate从
复制另一个关联实体的标识符。在Hibernate术语中,它被称为
外部生成器,但JPA映射读取更好并且鼓励

The MapsId annotation ask Hibernate to copy the identifier from another associated entity. In the Hibernate jargon, it is known as a foreign generator but the JPA mapping reads better and is encouraged

Person.java

Person.java

@Entity
public class Person {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "person_id")
    private Long id;

    @OneToOne(cascade = CascadeType.ALL)
    @PrimaryKeyJoinColumn
    private VitalStats vitalStats;       
}

VitalStats.java

VitalStats.java

@Entity
public class VitalStats 
{
    @Id @Column(name="vitalstats_id") Long id;

    @MapsId 
    @OneToOne(mappedBy = "vitalStats")
    @JoinColumn(name = "vitalstats_id")   //same name as id @Column
    private Person person;

    private String stats;
}

人员数据库表

CREATE TABLE  person (
  person_id   bigint(20) NOT NULL auto_increment,
  name        varchar(255) default NULL,
  PRIMARY KEY  (`person_id`)
) 

VitalStats数据库表

CREATE TABLE  vitalstats 
(
  vitalstats_id  bigint(20) NOT NULL,
  stats          varchar(255) default NULL,
  PRIMARY KEY  (`vitalstats_id`)
)

这篇关于具有共享ID的JPA @OneToOne - 我可以做得更好吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆