0

我有以下使用 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
}

这很好用,因为我直接对休眠查询结果进行操作。但是,我也想将 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 转换为对象数组。

我尝试使用 jackson hibernate 模块,但这也无济于事。所以我的问题是:a)使用 JSON 序列化执行此操作的正确方法是什么?b)为什么杰克逊将其反序列化为数组列表?

4

1 回答 1

0

假设

当使用 jackson 进行序列化时,您的列表将类似于: [[A_item, B_item], [A_item2, B_item2], ... [A_itemn, B_itemn]] 为什么?因为如果您愿意,您有一个列表列表或数组数组(第二个列表总是有两个元素,A 和 B)。

问题

您的列表没有类型。所以杰克逊会将 json 流反序列化为列表列表。因为当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 提供了很多 jackson 没有的其他不错的功能,请查看 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 ;)

于 2012-08-25T23:32:29.227 回答