2011-11-30 41 views
1

假設有三類:我從一個類怎麼能轉換爲另一個類休眠

之一是:

@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然後它給出類拋出異常。請告訴我如何在合併時在休眠中投射類。

我的做法是這樣的:

//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

你就不能。 Hibernate在將對象類型保存到數據庫時保留它們。而Java在不兼容的情況下阻止從一種類型轉換爲另一種類型的對象。

對於您的情況,您不能在B中投射C的實例。這就像將String投射到Integer中一樣。

你最好的辦法是寫一個方法,它需要一個C的實例並將C的所有屬性複製到B類型的新對象中。

+0

是。這本身不是休眠問題;這是一個Java問題。 –

+3

它甚至不是一個Java問題,它是一個實現/設計問題 –

0

adminService.getA(request.getParameter("id"));實際上做了什麼?如果它的確如此:

hibernateSession.get(A.class,id);

則Hibernate將與該ID的行獲取的corresponing值,並創建你作爲參數傳遞的類A的一個實例(這就是爲什麼你通過它在那裏,從的Javadoc:「返回的持久實例給定的實體類別與給定的標識符「)。這意味着即使你聲明瞭你的Hibernate繼承,這樣Entity C擴展了Entity B擴展了Entity A,並且相應的類以相同的方式擴展了其他類,Hibernate實際上會創建一個A的實例(不是B或C的實例您ADRESS爲A),所以該實例不能強制轉換爲B.

但是,如果有對應的行是B型的ID(假設),那麼如果你

A a = hibernateSession.get(B.class,id); 

那麼你可以做

B b = (B)a; 

,因爲你的「一「objet是B型的事實(即使你最初把它當作A)。然而,在這種情況下,這將是簡單的只是:

B b = hibernateSession.get(B.class,id); 

同樣,上面會,如果你確實在該行中保存的B型(或C)的實體與該ID的工作原理(即你的鑑別科拉姆包含類型B或C的值)