如何在hibernate中从一个类转换为另一个类

时间:2011-11-30 13:03:12

标签: java hibernate jpa

假设有三个类:

一个是:

@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);

2 个答案:

答案 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的值),则上述操作将起作用