【问题标题】:How does composition work in Hibernate?组合在 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

【问题讨论】:

    标签: java hibernate composition


    【解决方案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等。
      猜你喜欢
      • 2017-11-08
      • 2012-03-31
      • 2017-10-25
      • 2023-04-06
      • 2016-06-02
      • 2013-02-14
      • 2012-09-13
      • 2017-08-15
      • 2015-03-30
      相关资源
      最近更新 更多