天天看点

XStream的局限性

最近做XStream结合Hibernate持久化的应用,克服了重重困难,可以让实体和xml之间相互自由转换。但从中也发现了XStream应用的一些局限性。

XStream在转换有关联的Hibernate实体时,会发生异常痛苦的循环嵌入问题,导致不可预期的结果。

问题提出:

比如有两张通过外间约束的表,假设叫tclass和student表,student有个外间关联tclass表的主键。在做Hibernate映射的时候,有两种选择:

1、做强关联,也就是在Student类中有一个TClass的实体属性。如果是双向的,在TClass类中还有一个Set<Student>,用来记录班级中包含的学生。大多这种多对一模型会选择强关联。这种关联适用于一个领域内部的关联。

2、做弱关联,也就是仅仅在Student类中有一个tcalssId,用来记录关联班级的ID属性。这个时候,数据库的外键关系是隐含的,没有SQL语法上的外键约束。做映射的时候,两个表都做单表映射。这种映射策略常常用于一个领域外部的关联。

说明:如果你对领域模型还不熟悉,可以先看看领域模型驱动设计。

这两种映射仅仅是Hibernate编程策略的两个选择,他们对应的数据表结构是完全一样的。在student表中仅仅会记录一个class表记录的Id。

加入选择的多对一关联是强关联。那么在转换Student实体对象到Student.xml的时候,会将Student类的TClass对象一块转换。但是往往真正需要的是TClass的id,而非TClass实体,假如做了双向关联,TClass实体里又包含了Student的集合,转换过程就成了一个相互包含的死循环。这当然不是想要的结果。

解决方案:

1、Hibernate做弱关联。

      优点:XStream可以直接转换实体,非常方便。

      缺点:打破了领域模型设计的思路,不符合面向对象的设计逻辑,编程会很别扭。

2、重新实现XStream的转换器com.thoughtworks.xstream.converters.Converter接口,实现转换过程全程控制。

      优点:保持了领域模型设计和Hibernate的映射策略。

      缺点:要自己实现Converter接口,很麻烦,一个实体对应一个Converter接口,工作量加大,容易出错,一旦实体改变,Converter的实现也改变,维护困难。与其这样,还不如手写工具将实体转换为XML。

这两个解决方案不好分个高低。关键是要知道XStream的长处,能做什么,短处,不能做什么。在应用之前都应该考虑到扬长避短。这样不至于过后亡羊补牢,给项目带来风险。

本文转自 leizhimin 51CTO博客,原文链接:http://blog.51cto.com/lavasoft/79211,如需转载请自行联系原作者