【问题标题】:JPA (Hibernate) OneToOne Impedance MismatchJPA(休眠)OneToOne 阻抗不匹配
【发布时间】:2019-01-27 22:07:30
【问题描述】:

我正在研究 JPA 和 Hibernate 以构建 Spring Boot webapp,但有些事情让我很困扰。 它与一对一关系中的阻抗不匹配有关。

假设我有两个域实体 A 和 B,它们具有一对一的关系。

这是我想要的:

  • 在 Java 类中,我希望 A 持有对 B 的引用;
  • 在数据库中,我希望“b”对象的表有一个列,其中包含“a”键的外键。

有没有办法在 Spring Boot 中使用 JPA 和 Hibernate 来做到这一点?


我在这里报告现实世界的类和代码的问题。

在我的域中,我基本上有人员和签名。 因此,在我的 Java 代码中,我有 Person @Entity 和 Signature @Entity。

在 Java 中,让 Person 对象拥有一个 Signature 对象是有意义的。 所以,这里是 Person 类:

@Entity
@Table(name = "people")
public class Person {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private long id;

    @Column(name="first_name")
    @NotNull
    @NotBlank
    @Size(min = 3, max = 100)
    private String firstName;

    @Column(name="last_name")
    @NotNull
    @NotBlank
    @Size(min = 3, max = 100)
    private String lastName;

    // ??? which annotations?
    private Signature signature;

    // I omit constructors, getters and setters for brevity

这是 Signature 类:

@Entity
@Table(name = "signatures")
public class Signature {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private long id;

    @Column(name="name")
    @NotNull
    @NotBlank
    private String name;

    @Column(name="type")
    @NotNull
    private String type;

    @Column(name="image")
    @NotNull
    @NotEmpty
    @Lob
    @Type(type="org.hibernate.type.MaterializedBlobType")
    private byte[] image;

    // I omit constructors, getters and setters for brevity

如您所见,ID 应该是自动生成的,我希望我的 Person 类具有对其 S​​ignature 的引用,而不是相反。

相反,这是我想使用的数据库架构:

CREATE SCHEMA signatures;

CREATE TABLE signatures.people (
   id BIGSERIAL,
   first_name VARCHAR(100) NOT NULL,
   last_name VARCHAR(100) NOT NULL,
   PRIMARY KEY (id)
);

CREATE TABLE signatures.signatures (
   id BIGSERIAL,
   type VARCHAR[16] NOT NULL,
   name VARCHAR[100] NOT NULL,
   image BYTEA NOT NULL,
   person BIGINT NOT NULL,

   PRIMARY KEY (id),
   CONSTRAINT fk_signature_people FOREIGN KEY (person) REFERENCES signatures.people (id) ON DELETE CASCADE ON UPDATE CASCADE
);

正如您在此处看到的,我希望 Signatures 表具有 People 表的外键,反之亦然。

这可能吗?

【问题讨论】:

    标签: java hibernate spring-boot jpa orm


    【解决方案1】:

    @OneToOne 映射有点奇怪。当关系是双向时,您可以决定拥有方,但在单向关系中,声明实体将始终是具有外键的实体。

    一种选择是使关系双向,但在代码中隐藏另一个方向。

    另一种方法是使用@OneToMany 映射,它将在“many”表中创建外键。这也与数据库架构一致,因为至少在理论上,多个子表行可以链接到同一个父行,尤其是在没有确保它们唯一的约束的情况下。

    【讨论】:

    • 不幸的是它似乎不起作用:(我收到以下错误:“引用的属性未知:com.demo.example.model.Signature.signatures”它在签名对象。
    • @AndreaRossi 啊,对。有没有机会使链接成为双向的?
    • 您可以将其设为双向并阻止所有对另一个方向的访问(如果这真的很重要),或者您可以尝试使用@OneToMany,这将创建@987654324 的外键@,但你会有一个 1 号的 Set。似乎不可能用@OneToOne 获得反面的外键。
    • 好的,我已经用@OneToMany 方法实现了它,它似乎工作正常。感谢您的支持!如果您对此解决方法写了完整的答案,我会接受它:)
    猜你喜欢
    • 2021-06-25
    • 2012-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-13
    • 1970-01-01
    • 2012-10-14
    • 2011-02-25
    相关资源
    最近更新 更多