组合在 Hibernate 中是如何工作的?

Posted

技术标签:

【中文标题】组合在 Hibernate 中是如何工作的?【英文标题】:How does composition work in Hibernate? 【发布时间】:2010-11-26 11:22:58 【问题描述】:

我正在尝试在带有注释的休眠中使用组合。

我有:

@Entity
@Table(name = "Foo")
public class Foo 
    private Bar bar;

    public void setBar(Bar bar)...
    public Bar getBar() ...)


public class Bar 
  private double x;

  public void setX(double x) ...
  public double getX() ...

当试图拯救 Foo 时,我得到了

无法确定实体的类型 org.bla.Bar 表 Foo 中的列: [org.hibernate.mapping.Column(bar)]

我尝试在 Bar 上添加一个 @Entity 注释,但这让我很兴奋:

没有为实体指定标识符 org.bla.Bar

【问题讨论】:

【参考方案1】:

您需要指定FooBar 之间的关系(例如@ManyToOne 或@OneToOne)。

或者,如果Bar 不是实体,则用@Embeddable 标记它,并将@Embedded 添加到Foo 中的变量声明中。

@Entity
@Table(name = "Foo")
public class Foo 
    @Embedded
    private Bar bar;

    public void setBar(Bar bar)...
    public Bar getBar() ...)


@Embeddable
public class Bar 
  private double x;

  public void setX(double x) ...
  public double getX() ...

参见:https://www.baeldung.com/jpa-embedded-embeddable——该示例解释了@Embeddable 和@Embedded Composite 方式,其中FooBar(示例中为CompanyContactPerson)映射在同一个表中。

【讨论】:

我正在阅读您发送的链接 - 我相信它假设我想规范化表格表示。但是,我认为就我而言,我更喜欢将这些列嵌入到一个主表中。含义 - 我想要一张表,其中包含 Foo & Bar 的所有字段作为列。假设这确实是我想要的 - 我如何使用 Hibernate 来实现? @Ripper234:不,看看示例中的表格,它包含学生和地址字段。 (ER-Diagramme 有点混乱,因为它显示了更合乎逻辑的视图,而不是数据库。) @Embeddable@Embedded 不是休眠注释,它们仅在 JPA 中可用。您链接到的教程非常糟糕(不仅因为它没有提到它正在使用 JPA) 谢谢,我只是错过了@Embedded 注释。请编辑您的答案以包含此内容。 为了限定我的上述陈述:它们是 JPA 注释,但它们显然是标准的休眠方式(见我的回答)【参考方案2】:

该机制在参考文档的这一部分中进行了描述:

5.1.5. Embedded objects (aka components)

显然hibernate为此使用了JPA注解,所以referred to by Ralph的解决方案是正确的

简而言之:

如果将类Address 标记为@Embeddable 并将Address 类型的属性添加到类User,将该属性标记为@Embedded,则生成的数据库表User 将包含所有字段由Address指定。

请参阅 Ralph 对代码的回答。

【讨论】:

【参考方案3】:

每个simple实体都必须标记为实体(使用@Entity)并具有一个标识符(主要是Long)作为主键。每个非原始关联/组合都必须使用相应的关联注释(@OneToOne@OneToMany@ManyToMany)进行声明。我建议你通读Hibernate Getting Started Guide。请尝试以下操作以使您的代码示例正常工作

@Entity
public class Foo 
    @Id
    @GeneratedValue
    private Long id;

    @OneToOne
    private Bar bar;

    // getters and setters for id and bar


@Entity
public class Bar 
    @Id
    @GeneratedValue
    private Long id;

    private double x;

    // getters and setters for id and x

【讨论】:

这会创建两个单独的表,但 OP 想要 foo 表中的 bar 字段。 @Sean Patrick Floyd 不一定。 “组合”是指 Java 代码和一般的 OOP,而不是数据库映射。 OOP组合可以多种方式映射存储,包括@OneToOne(使用外键)、@OneToOne(使用共享主键)、@Embedded等。

以上是关于组合在 Hibernate 中是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章

片段组合在 Relay 中是如何工作的?

Java 11:OSGi:生成 EntityManager,无法构建 Hibernate SessionFactory java.lang.ClassNotFoundException:org.hib

Hibernate参考文档

学习hibernate

如何在 postgres 中设置锁定超时 - Hibernate

hibernate如何生成外键约束名?