超级存在时创建缺少的子类实体

时间:2017-10-10 16:03:34

标签: java hibernate left-join entity hql

我在数据库上有2个表 S I (具有1:1的关系),它们都具有与pk相同的id和hibernate类I'创建的是这样的:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class S {
   @Id
   @Column(name = "id")
   @GeneratedValue(...)
   @SequenceGenerator...
   private long id;

   ....
}

@Entity
@PrimaryKeyJoinColumn(name = "id")
public class I extends S {
    ....
}

由于历史原因,在数据库中存在类型为 S 的对象,但没有 I 类型的关联对象。我想使用hibernate创建那些 I 类型的对象。我怎样才能做到这一点?我可以从左连接HQL查询中创建 I 类型对象吗?

select i from I i right join i.id s where s.id = :id

如果我尝试创建一个新的 I 实体(新的I())然后继续它,我只是设法得到一些例外,因为它试图创建一个已经存在的 S < / strong>记录。我无法对实体进行简单的读取/加载,因为记录尚不存在。如何创建缺少的 I 部分实体?

PS如果你指出不清楚的事情,我会调整问题

2 个答案:

答案 0 :(得分:0)

一种肯定适合你的方法(虽然不是很干净)是直接用SQL插入创建I记录:insert into I_table values (...)。 当I_table中有相应的记录时,ORM会开始使用I类型加载对象。

如果您必须使用ORM并且可以删除S记录,那么您可以

  1. 按ID
  2. 加载S
  3. 删除S(根据您的刷新模式刷新?)
  4. 创建I
  5. S值复制到I
  6. 保存I

答案 1 :(得分:0)

您尝试创建的是实体层次结构。所以必须正确映射实体。以下可能是您所需要的:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(discriminatorType = DiscriminatorType.CHAR)
@DiscriminatorValue("S")
public class S {
   @Id
   //........
   private long id;

   ....
}

@Entity
@DiscriminatorValue("I")
public class I extends S {
    ....
}
  • 使用此设置,表S将包含一个名为DTYPE的列(用于鉴别器类型),用于标识行是属于S还是I;这是默认值;如果您不想要,则必须为DiscriminatorColumn注释命名。

  • 创建S的实例并保存

  • 创建&#39; I&#39;通过填充继承的属性(即S的属性)及其自己的属性,并保存。

  • 当您创建定位I的查询时,您只会获得I的实例,但如果您的查询定位到S,那么您就会获取两个实体的实例。