使用 Eclipselink/JPA 更改实体类型?

Change entity type with Eclipselink / JPA?

我知道 similar questions,但他们在 Hibernate 的范围内被询问和回答。我遇到了同样的问题,但我正在使用 Eclipselink 并想知道是否有针对 Hibernate 的建议的更好或替代解决方案。

简要回顾一下问题:

我有两个 类 相互继承:

@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="dtype")
@DiscriminatorValue(value="parent")
public class Parent {
  @Id
  private long id;
}


@Entity
@DiscriminatorValue(value="child")
public class Child extends Parent{
   private String childProperty;
}

现在我想将 Child 更改为 Parent,反之亦然,例如

Parent p = new Parent();
em.persist(p);

Child c = (Child) p;
em.merge(c);

我希望 p 现在的数据库行是 dtype = child

另一种方式是这样的:

Child c = new Child();
em.persist(c);

Parent c = (Parent) c;
em.merge(c);

在这种情况下,我希望 cdtype = parent 一起保存并丢失 childProperty 的值。

虽然上面描述的不起作用,但我写下来以表明我的意思。

有没有办法用 Eclipselink 做到这一点?

如果您想 'change' 一个 object 从一种类型到另一种类型,java 或 JPA 继承没有简单的解决方案。您必须克隆您的实例,删除旧实例,然后将新实例保留为 JPA/Java 兼容:

Child c = em.find(pk, Child.class);
Parent p = new Parent();
p.setId(c.getId());
p.setOtherFields(c.getOtherFields());

em.getTransaction().begin();
em.remove(c);
em.getTransaction().commit();
em.clear();
em.getTransaction().begin();
em.persist(p);
em.getTransaction().commit();

对所有事务使用相同的事务 'might' 使用刷新而不是 commit/begin 工作,但不能保证,因为管理二级缓存变得棘手。另请注意,与 child 的所有关系都需要更新以指向 'new' parent 实例,否则缓存将被破坏。

虽然我不太确定这一点,因为在这种情况下 Child 是一个 parent 实例。除了数据库中的任意标志外,这种方法没有任何好处。如果您希望它可以即时更改,使用 Java 子类可能不适合您的应用程序。

相反,我建议使用具有字段的通用 Person,您可以将其设置为保持 child/parent 状态。但是因为 child 可以同时是 parent..