Gson转换hibernate级联对象的处理

在使用gson架包转换hibernate级联对象为json字符串的时候,有两个问题需要注意:
类被设置为延迟加载时,转换延迟加载的对象为json时报异常。
< many-to-one>和< one-to-many>属性的对象级联关系在转换时会造成死循环,报stackOverFlowException。

现有如下级联关系类:
Gson转换hibernate级联对象的处理_第1张图片
hibernate级联关系对象
Device类中存在DeviceRelation对象一对一,User对象多对一和DeviceType对象多对一的引用。在将一个Device对象转换成json字符串的时候就会出现上述两种问题。

解决方法: 问题一: 在hibernate中,默认类对象加载策略为延迟加载,那么当使用默认加载策略时,若要转换device对象时,其中的引用对象不会自动从数据库加载并转换为json格式。 解决办法为关闭延迟加载策略,即lazy=”false”;
问题二: 对于hibernate中的一对一级联关系,gson可以正常转换,但是对于一对多,多对一,多对多关系,会造成死循环最终抛stackoverFlow异常。原因如下: gson转换对象时,是按照对象中的成员变量的顺序转换的,对于device对象,转换顺序:
user对象引用
name字符串
num字符串
deviceType对象引用
deviceRelation对象引用
在转换user对象引用时,又会按顺序转换user对象内部成员变量属性: 1.devices集合 2.count整数 3.addr字符串 4.area对象引用 然而devices集合又是由device对象所组成,那么就会依次转换该集合中的所有device对象。同理对于所有的一对多和多对一,多对多关系,都会如此处理,造成循环,并最终导致异常抛出。 解决方法: 使用Gson API中的@Expose注解,标志所有需要转换的属性,并在生成gson转换器的时候使用excludeFieldsWithoutExposeAnnotation()方法创建。

Device类bean 将device类中的所有属性都注解为@Expose,表示在转换时,所有成员变量属性都转换。

public class Device implements Comparable,Serializable,Cloneable{   
@Expose private Integer id;
@Expose private String name;
@Expose private String addr;
@Expose private String deviceNo;
@Expose private User user;
@Expose private DeviceRelation deviceRelation;
@Expose private DeviceType deviceType;
//setter getter方法.........
}

User类的处理: 将user类中的< many-to-one>和< one-to-many>属性都排除在转换属性之外,不使用@Expose注解标志,那么在转换json字符串的时候,就会忽略掉没有标注的成员换变量。

public class User implements Serializable {
@Expose private Integer id;
@Expose private String userNo;
@Expose private String name;
@Expose private Area area;
@Expose private Bank bank;
private Set devices = new HashSet<>();
//setter getter方法.........
}

deviceType类的处理 同上述user类一样,去掉一对多,多对一和多对多的级联属性。
public class DeviceType implements Serializable{@Expose private Integer id;@Expose private String name;private Setdevices = new HashSet<>();//setter getter方法.........}

public class DeviceType implements Serializable{
@Expose private Integer id;
@Expose private String name;
private Setdevices = new HashSet<>();
//setter getter方法.........
}

并使用

Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();

上述gson对象转换处理之后的device对象即可解决上述两个问题。

转自:http://blog.csdn.net/qq1004642027/article/details/50296257

你可能感兴趣的:(Gson转换hibernate级联对象的处理)