【问题标题】:Hibernate OneToOne mapping to different tablesHibernate OneToOne 映射到不同的表
【发布时间】:2015-05-12 22:33:52
【问题描述】:

我需要保存一个数据结构,它的值可以是字符串、双精度或日期。

有没有办法根据表格进行一对一映射?

我试过了……

@Table(name = "FIELD_CRITERIA")
public class FieldCriteriaEntity implements Identifiable{

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "CRITERIA_KEY", unique = true, nullable = false)
    private Long id;

    @OneToOne(fetch = FetchType.EAGER, cascade =  CascadeType.ALL,optional=true)
    @JoinColumn(name="CRITERIA_ID")
    private StringCriteriaEntity stringCriteria;

    @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL,optional=true)
    @JoinColumn(name="CRITERIA_ID")
    private NumeriCriteriaEntity numericCriteria;

    @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL,optional=true)
    @JoinColumn(name="CRITERIA_ID")
    private DateCriteriaEntity dateCriteria;
}

但是,hibernate 不喜欢这样:

原因:org.hibernate.MappingException:实体映射中的重复列:

有没有办法配置休眠来处理这个问题?还是我应该简单地重新建模 FIELD_CRITERIA 表以包含 3 个可选的 OneToMany 关系?

【问题讨论】:

    标签: java database hibernate database-design


    【解决方案1】:

    首先,您可以尝试将 DateCriteriaEntity 和 NumericCriteriaEntity 设为“一对一”关系的所有者,而不是 FieldCriteriaEntity。将 CRITERIA_ID 列移动到与 NumericCriteriaEntity 和 DateCriteriaEntity 对应的表中,以便该列将 FieldCriteriaEntity id 存储为外键,并在 FieldCriteriaEntity 中使用 @OneToMany(mappedBy="correspondent field name") 而不是您的变体。

    考虑这篇文章http://uaihebert.com/jpa-onetoone-unidirectional-and-bidirectional/

    【讨论】:

      【解决方案2】:

      我想实现这一点的更好方法是稍微修改你的实体设计。请看下面的类图。您可以创建一个抽象的 CriteriaEntity,它将以 criteriaId 作为主键。请仔细选择子类的继承策略。如果条件实体相对简单,则考虑使用 SINGLE_TABLE 或移至 TABLE_PER_CLASS。

      @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
      

      您将需要修改您的FieldCriteriaEntity 以仅使用一个映射。请看下文

      @Table(name = "FIELD_CRITERIA")
      public class FieldCriteriaEntity implements Identifiable{
      
          @Id
          @GeneratedValue(strategy = GenerationType.AUTO)
          @Column(name = "CRITERIA_KEY", unique = true, nullable = false)
          private Long id;
      
          @OneToOne(fetch = FetchType.EAGER, cascade =  CascadeType.ALL,optional=true)
          @JoinColumn(name="CRITERIA_ID")
          private CriteriaEntity criteria;
      }
      

      希望这会有所帮助!

      【讨论】:

      • 我已尝试实施您的建议,但我遇到了抽象类的问题。 @Entity @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) 公共抽象类 FieldCriteriaEntity 错误是:引起:org.hibernate.AnnotationException:没有为实体指定标识符:murex.risk.compliance.excess.entities.FieldCriteriaEntity
      • 为什么我需要为实体指定一个标识符,如果它是抽象的。
      • 抱歉小伙伴忘记在我之前的帖子中提到了,criteriaId 需要使用@Id 注解声明为主键。您的情况下的外键需要是关联实体或表中的主键。
      猜你喜欢
      • 2020-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-12
      • 1970-01-01
      相关资源
      最近更新 更多