这是我找不到解决方案的问题,我想,这要么是不可能的,要么我的整个想法走错了方向。
最初我的 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 {...}
我尝试了不同的选择,但总是有一个问题:
我猜,JPA 提供程序(在我的情况下是休眠)首先插入父级,因此它
CF_OBJECT_ID
是null
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) 值 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
如果我在基本实体上省略
@PrimaryKeyJoinColumn
注释,则其后代的 sId
和Id
s 用作连接列,它导致子类表没有相同的 id。一开始这很好,但是我们已经在两个表中拥有大量记录,并且它们在id
列中具有相同的值。更改表中的 s 不是一种选择id
。
在我的情况下使用继承的正确方法是什么,所以它尽可能无缝地进入?很高兴了解如何首先使休眠持久子类实例,然后将其 id 传递给持久化的超类。必须有注释,对吧?
编辑:至于使用建议@MappedSuperclass
@MappedSuperClass
由于以下原因,我真的不能使用 a 。父类EntityWithCustomFields
用于通过类的ManyToOne
关系来引用CustomFieldValue
。在代码中,它如下所示:
@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
可以用于这种东西。