如何正确地序列化Hibernate集合?

时间:2008-10-08 11:48:48

标签: java hibernate serialization collections

我正在尝试从使用Hibernate检索的数据库中序列化对象,我只对整个对象的实际数据感兴趣(包括循环)。

现在我一直在使用XStream,这似乎很有用。 XStream的问题在于它对信息的看法太过盲目。它可以识别Hibernate的PersistentCollections,包含所有Hibernate元数据。我不想序列化这些。

那么,是否有合理的方法从PersistentCollection中提取原始Collection,并初始化对象可能指向的所有引用数据。或者你能推荐我一个更好的方法吗?

(来自Simple的结果似乎很完美,但是它无法处理像Calendar这样的基本util类。它一次只接受一个带注释的对象)

3 个答案:

答案 0 :(得分:1)

我推荐一种更简单的方法:用户推土机:http://dozer.sf.net。 Dozer是一个bean映射器,你可以使用它将PersonEJB转换为同一个类的对象。 Dozer将通过getter()调用递归触发所有代理fecthes,并将src类型转换为dest类型(比如说java.sql.date到java.utilDate)。

这是一个片段:

MapperIF mapper = DozerBeanMapperSingletonWrapper.getInstance();
PersonEJB serializablePerson = mapper.map(myPersonInstance, PersonEJB.class);

请记住,当推土机遍历您的对象树时,它将逐个触发代理加载,因此如果您的对象图有许多代理,您将看到许多查询,这可能很昂贵。

答案 1 :(得分:1)

这里描述的解决方案对我来说效果很好:http://jira.codehaus.org/browse/XSTR-226

我们的想法是为hibernate集合提供自定义XStream转换器/映射器,它将从hibernate集合中提取实际集合,并将调用相应的标准转换器(对于ArrayList,HashMap等)。

答案 2 :(得分:0)

通常似乎是最好的方法,而我目前正在这样做的方法是拥有另一层DTO对象。这样,您可以排除不希望通过通道的数据,也可以限制图表序列化的深度。我将Dozer用于从Hibernate对象到Flex客户端的当前DTO(数据传输对象)。

效果很好,但需要注意几点:

  • 它并不快,实际上它非常缓慢。如果您发送大量数据,Dozer将无法很好地执行。这主要是因为反射涉及表现其魔力。
  • 在少数情况下,您必须为特殊行为编写自定义转换器。这些工作非常好,但它们是双向的。我个人不得不破解Dozer源,以允许单向定制转换器。