【问题标题】:Introduce joined JPA inheritance into already existing database将加入的 JPA 继承引入现有数据库
【发布时间】:2012-05-16 05:32:01
【问题描述】:

这是我找不到解决方案的问题,我想这要么是不可能的,要么是我的整个想法都朝着错误的方向发展。

最初我的 JPA 层次结构的一部分是这样的:

@MappedSuperclass
public abstract class AbstractEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    protected Long id;
    ..... 
}

@Audited
@Entity
@Table(name = "T_MEETING")
public class Meeting extends AbstractEntity implements Groupable {...}

@Audited
@Entity
@Table(name = "T_QUESTION")
public class Question extends AbstractEntity implements Groupable {...}

这个数据库已经使用了一段时间,直到需要在某些对象中自定义字段。

我决定遵循以下路线 - 将抽象实体作为具有自定义字段的对象的基础:

@Audited
@Entity
@Table(name = "T_CF_OBJECT")
@Inheritance(strategy = InheritanceType.JOINED)
@PrimaryKeyJoinColumn(name = "ID", referencedColumnName = "CF_OBJECT_ID")
public abstract class EntityWithCustomFields extends AbstractEntity {...}

@Audited
@Entity
@Table(name = "T_QUESTION")
public class Question extends EntityWithCustomFields implements Groupable {...}

@Audited
@Entity
@Table(name = "T_MEETING")
public class Meeting extends EntityWithCustomFields implements Groupable {...}

我尝试了不同的选项,但总是有问题:

  1. 我猜,JPA 提供程序(在我的情况下是休眠的)首先插入父级,因此它的 CF_OBJECT_IDnull

    Hibernate:插入 t_cf_object (id, cf_object_id) 值 (null, ?) Hibernate:插入 t_meeting (active, date, c_group, last_notification_date, only_for_members, place, questions_order, subject, update_date, id) 值 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

  2. 1234563 ID。一开始这很好,但是我们已经在两个表中都有大量记录,并且它们在id 列中具有相同的值。不能更改表格中的ids。

在我的情况下使用继承的正确方法是什么,以便尽可能无缝地进入?很高兴了解如何首先使休眠持久子类实例,然后将其 id 传递给持久的超类。必须有注释,对吧?

编辑:至于建议使用@MappedSuperclass

由于以下原因,我真的不能使用@MappedSuperClass。父类EntityWithCustomFields 用于通过CustomFieldValue 类的ManyToOne 关系引用。代码如下:

@Entity
@Audited
@Table(name = "T_CF_VALUES")
public class CustomFieldValue extends AbstractEntity {
    @ManyToOne
    @JoinColumn(name = "customFieldObject", nullable = false)
    private EntityWithCustomFields customFieldObject;
    ....
}
@Audited
@Entity
@Table(name = "T_CF_OBJECT")
@Inheritance(strategy = InheritanceType.JOINED)
@PrimaryKeyJoinColumn(name = "ID", referencedColumnName = "CF_OBJECT_ID")
public abstract class EntityWithCustomFields extends AbstractEntity {
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "customFieldObject", cascade = CascadeType.ALL)
    private List<CustomFieldValue> customFields;
    ....
 }

我认为@MappedSuperclass 不能用于这类事情。

【问题讨论】:

    标签: hibernate inheritance jpa


    【解决方案1】:

    在我看来,您不希望在此处继承实体,而是希望为您的实体提供具有自定义字段的附加映射超类。

    当你有一个真正的 is-a 函数关系时,必须使用实体继承。例如,一张发票可能有一个产品列表,而产品实体将是继承树的根(蔬菜、肉类、衣服等)。在这种情况下,蔬菜是一种产品,当然两个产品可能没有相同的 ID,因为例如价格实体可以通过外键引用产品,如果两个产品具有相同的 ID,它就不会根本不工作。

    在您的情况下,具有自定义字段的实体完全不相关。它们只是碰巧有公共字段,您想通过将这些公共字段放在超类中来考虑这一点。这就是 MappSuperclass 的用途。并且这些自定义字段应该在每个实体表中重复。无论如何,这将比联合继承更有效(这会导致更多的查询,以及更复杂和更难优化的查询)。

    【讨论】:

    • 我已经在回答我自己的问题时回答了您的评论
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-29
    • 2022-10-25
    • 1970-01-01
    • 1970-01-01
    • 2019-03-22
    • 2015-08-31
    • 2015-05-29
    相关资源
    最近更新 更多