使用 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);
在这种情况下,我希望 c
与 dtype = 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..
我知道 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);
在这种情况下,我希望 c
与 dtype = 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..