2012-08-25 137 views
0

我有以下代碼使用Hibernate3。Jackson Json序列化多個Hibernate對象

List queryResult = session.createQuery("SELECT A, B from A, B where A.id = B.id"); 
for (Object o: queryResult) { 
    Object[] array = (Objec[]) o; 
    A a = (A) array[0]; 
    B b = (B) array[1]; 
    //do work 
} 

這很好,因爲我操作直接對hibernate查詢結果。但是,我也想將queryResult序列化爲一個字符串,以便稍後使用它。我嘗試以下使用傑克遜的JSON庫:

ObjectMapper m = new ObjectMapper() 
final String queryResultString = m.writeValueAsString(queryResult); 

再後來我嘗試讀取和反序列化從Json的字符串返回到Hibernate的查詢結果,這是當我打的麻煩。讀取代碼:

List r = m.readValue(queryResultString, List.class); 
for (Object o: r) { 
    Object[] array = (Objec[]) o; 
    A a = (A) array[0]; 
    B b = (B) array[1]; 
    //do work 
} 

Object []的轉換抱怨無法將ArrayList轉換爲對象數組。

我試圖使用傑克遜休眠模塊,但這也沒有幫助。所以我的問題是:a)JSon序列化的正確方法是什麼? b)爲什麼傑克遜將其反序列化爲數組列表?

回答

0

假設

連載時與傑克遜列表將類似於: [A_item,B_item],[A_item2,B_item2],... [A_itemn,B_itemn] 爲什麼呢?因爲如果你喜歡,你有一個列表或數組數組的列表(第二個列表總是有兩個元素,A和B)。

問題

您的列表是類型化的。所以傑克遜會將json流設置爲列表清單。 因爲當jackson遇到一個數組結構並且不知道要反序列化的類型時,它將反序列化爲List而不是數組。

解決方案

1)而不是使用您使用列表陣列,因爲傑克遜將在默認情況下反序列化到一個列表,而不是一個數組(這就是爲什麼你有classcast除外)。

2)如果你在java 5+(這意味着你可以使用泛型),那麼你可以使用傑克遜TypeReference類。

List listOfLists = mapper.readValue(queryResultString, new TypeReference<List<Object[]>>() {}); 

3)你從傑克遜切換到Genson http://code.google.com/p/genson/時默認反序列化到陣列而不是一個列表。 Genson提供了傑克遜沒有的許多其他很好的功能,請參閱wiki http://code.google.com/p/genson/wiki/GettingStarted。 Genson要求java 6+

List r = new Genson().deserialize(queryResultString, List.class); 
for (Object o: r) { 
Object[] array = (Objec[]) o; 
    // it works! 
    A a = (A) array[0]; 
} 

編輯 您哈瓦foreach循環,我斷定你正在java的6+,然後切換到Genson;)

+0

2)不工作 - 它沒有傳遞對象[ ]鑄造語句,但實際鑄造對象(A)數組[0]失敗,出現異常:不能將LinkedHashMap轉換爲A. 3)Genson沒有工作,因爲它未能序列化A. –

+0

1)你的A和B是傑克遜默認並不知道什麼類型的反序列化的複雜類型。這就是爲什麼他反序列化到一個地圖。2)你能展示你的objets是什麼樣子嗎?我很驚訝序列化失敗... – eugen

+0

A和B是hibernate對象 - 即使用hibernate查詢mysql返回的對象。我認爲序列化可能會丟失類信息,並試圖爲對象映射添加hibernateModule,但它也不起作用。 –