当前位置: 首页 > 面试题库 >

具有共享ID的JPA @OneToOne —我可以做得更好吗?

班凌
2023-03-14
问题内容

我正在使用一个我不想更改的现有架构。该模式在表Person和VitalStats之间具有一对一关系,其中Person具有主键,而VitalStats使用相同的字段作为其主键和针对Person的外键,这意味着其值是相应PK的值人。

这些记录是由外部流程创建的,我的JPA代码从不需要更新VitalStats。对于我的对象模型,我希望我的Person类包含VitalStats成员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无效。\

如果我尝试

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

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

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

那么,是什么阻止了我只是说Person实现了Serializable?没什么,实际上,除了我喜欢代码中的所有内容是有原因的,而且我看不到任何逻辑,这使得我的代码可读性较差。

同时,我只是将VitalStats中的Person字段替换为一个长的personId,并使其成为VitalStats的@Id,所以现在@OneToOne可以使用。

所有这些解决方案(在我看来)都是一个简单的问题,有些笨拙,因此我想知道我是否缺少任何内容,或者是否有人至少可以向我解释为什么Person必须可序列化。

TIA


问题答案:

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

Hibernate参考文档的相关部分:

PrimaryKeyJoinColumn

PrimaryKeyJoinColumn注释确实表示该实体的主键用作关联实体的外键值。

MapsId

MapsId注释要求Hibernate从另一个关联的实体复制标识符。在Hibernate行话中,它被称为外来生成器,但JPA映射读起来更好,值得鼓励

人.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

@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`)
)


 类似资料:
  • 问题内容: 我正在尝试使用JPA / Hibernate设置以下表: 可能有很多用户,每个用户最多只能有一个验证码,也可能没有。 这是我的课程: 我创建一个用户,然后尝试使用以下代码添加验证代码: 当我尝试运行它时,我收到org.hibernate.PersistentObjectException:分离的实体传递给持久化:用户 我还尝试在Validation类中使用以下代码: 当我创建验证码时,

  • 我有一个这样的旋转器: 当用户点击时,我希望它保存状态: 它将位置保存在SharedPref中,但微调器将返回默认值。有人看到什么了吗?

  • 问题内容: 说我有一个摇摆的GUI,我想听。您认为谁应该是侦听器类,谁应该负责?实施它的最佳或首选方式是什么?有什么意见吗?我通常会这样: 有没有更好的办法? 编辑: 谢谢大家的智慧和帮助。我很感激。 问题答案: 有几种执行事件侦听器的常用方法(在下面的代码中,我想到的唯一一个就是静态内部类)。下面的代码使用ActionListener,因为它很简单,但是您可以将其应用于任何侦听器。 请注意,“这

  • 我了解到Bellman-Ford算法的运行时间为O(| E |*| V |),其中E是边的数量,V是顶点的数量。假设图没有任何负加权圈。 我的第一个问题是,我们如何证明在(| V |-1)迭代中(每次迭代检查E中的每条边),它更新到每个可能节点的最短路径,给定一个特定的起始节点?有没有可能我们已经迭代了(|V |-1)次,但仍然没有得到到每个节点的最短路径? 假设算法正确,我们真的能做得更好吗?我

  • 问题内容: 我想知道是否可以在打包中共享测试实用程序代码。具体来说,我正在编写一个TCP服务器,该服务器将由多个处理程序用于不同的消息类型,并希望重用一组常见的测试实用程序。 主要的TCP服务器代码在: 该代码旨在成为一个共享库,其他程序包和其他程序包可使用该共享库来设置测试服务器和客户端以对其进行测试。例如,在子包中,我有: 这些文件全部导入,但它们无法访问在中定义的测试实用程序: 看来测试可以

  • 将 User1 Bean 注入 Order1 类时出错 我正在使用@autowire@onetoMany是否允许?我添加了订单1.java,用户1.java,pom.xml和错误 pom.xml文件