假设有三个类:
一个是:
@Entity
@Indexed
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING)
@Table(name = "tbl_a")
public class A {
@Id
@DocumentId
@GeneratedValue(generator="rwSpecSeq")
@SequenceGenerator(name="rwSpecSeq", sequenceName="RW_SPEC_SEQ")
private int id;
private String sampleAttribute;
//Getters and Setters
}
@Entity
@DiscriminatorValue("b")
public class B extends A {
}
@Entity
@DiscriminatorValue("c")
public class C extends A {
}
如果一个对象被保存为B的对象,那么如果我想再次将对象转换或更改为C,那么它将给出类强制转换异常。请告诉我在合并时如何在hibernate中强制转换类。
我的方法是这样的:
//Assuming that the object is C class' object.
A a = adminService.getA(request.getParameter("id"));
//before merging I did this
B b = (B)a;
adminService.save(b);
答案 0 :(得分:2)
你不能。 Hibernate在持久化到数据库时保持对象类型。当Java不兼容时,Java会阻止将对象从一种类型转换为另一种类型。
在您的情况下,您无法在C
中投射B
的实例。这就像将String
投射到Integer
。
最好的方法是编写一个方法,该方法采用C
的实例,并将C
的所有属性复制到B
类型的新对象中。
答案 1 :(得分:0)
adminService.getA(request.getParameter("id"));
实际上做了什么?如果它像:
hibernateSession.get(的A.class,ID);
然后Hibernate将从具有该id的行中获取相应的值,并创建一个您作为参数传递的类A的实例(这就是为什么你从那里传递它,来自javadocs:“返回持久性的实例具有给定标识符的给定实体类“)。这意味着即使你已经宣布你的Hibernate继承使得实体C扩展实体B扩展实体A,并且相应的类以相同的方式扩展每个人,Hibernate实际上将创建A的实例(不是B或C的实例)您作为A)使用,因此A的实例不能转换为B。
然而,如果那里的id对应于B类的行(比方说),那么如果你这样做
A a = hibernateSession.get(B.class,id);
然后你可以做
B b = (B)a;
因为您的“a”对象实际上是B类(即使您最初将其视为A)。但是在这种情况下,这样做会更简单:
B b = hibernateSession.get(B.class,id);
同样,如果您实际在具有该ID的行中保存了B(或C)类型的实体(即您的鉴别器列包含类型B或C的值),则上述操作将起作用