我使用Hibernate3获得以下代码。
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序列化为一个字符串,以便我以后可以使用它。我使用Jackson的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强制转换为对象数组。
我尝试使用jackson hibernate模块,但这也无济于事。所以我的问题是:a)使用JSon序列化的正确方法是什么? b)为什么杰克逊将其反序列化为arraylist?
答案 0 :(得分:0)
<强>假设强>
当使用jackson序列化时,您的列表将类似于: [[A_item,B_item],[A_item2,B_item2],... [A_itemn,B_itemn]] 为什么?因为你有一个列表或数组数组(第二个列表总是有两个元素,A和B)。
问题
您的列表是无类型的。所以杰克逊将把json流deseriliaze到列表列表。 因为当jackson遇到数组结构并且不知道要反序列化的类型时,它将反序列化为List而不是数组。
<强>解决方案强>
1)而不是使用数组,你使用列表,因为杰克逊默认反序列化为列表而不是数组(这就是为什么你有classcast异常)。
2)如果你在 java 5 + (这意味着你可以使用泛型),那么你可以使用jackson TypeReference类。
List listOfLists = mapper.readValue(queryResultString, new TypeReference<List<Object[]>>() {});
3)你从Jackson切换到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;)