我知道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做到这一点?
答案 0 :(得分:2)
如果要将对象从一种类型“更改”为另一种类型,则没有简单的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();
对它使用相同的事务所有'可能'使用flush而不是commit / begin,但是不能保证因为管理二级缓存变得棘手。另请注意,需要更新与子项的所有关系以指向“新”父实例,否则缓存将被损坏。
我不太确定这一点,因为在这种情况下,Child已经是一个父实例。除了数据库中的任意标志之外,这种方法没有获得任何东西。如果您希望它可以随时更改,那么使用Java子类可能不适合您的应用程序。
相反,我建议使用具有可设置为保持子/父状态的字段的通用Person。但由于孩子可以同时成为父母..