Hibernate之关系延迟加载(json死循环问题的解决方法)

问题

在SSH框架对一些一对多,多对多关联关系的数据做分页查询的时候,出现了死循环的状态

原因(你中有我,我中有你)

原因在于你要转化的对象里配置了对另外一个对象的关联,而那个对象里又配置了对你这个对象的关联。比如我的两个类叫Shop(商店)和Staff(员工),一个商店可以有多个员工,我给这两个对象配置了双向的一对多和多对一的关联关系。这时候问题出现了,JSON lib在把shop对象转化为json字符串的时候,发现shop里有个Set<Staff>,它就会去级联的把Set<Staff>转化为json字符串,在它遍历Set的时候,发现Staff里又有一个Shop对象,这时候它又会去尝试把shop转化为json字符串,然后就发现shop里又有Set<Staff>,如此周而复始,就形成了死循环。

Shop对象---套入Staff对象---Shop对象套入
{
    name:..
    id:..
    staff:[
        {age:..,sex:..,shop:{name:..,id:..,staff:[...]}}
    ]
        
   
}

解决

解决方法一(页面上不需要展示某一相关联数据):在将对象转成Json数据时,将相关联的数据属性排除

JsonConfig config = new JsonConfig();
           config.setExcludes(new String[]{"currentPage","pageSize","detachedCriteria","Subareas");

解决方法二(全能):1.在hbm文件相关属性上将延迟加载设成立即加载

lazy="false"

 2. A-B关联,在A类中获取数据JSON,我们只需要调取B中的数据信息,不需要B中再次对A的引用对象信息,将其去除,要不还是死循环

A{                                          B{

  id                                                sex                    

   age                                             home

   B                                                 A

}                                             }

JsonConfig config = new JsonConfig();

config.setExcludes(new String[]{"currentPage","pageSize","detachedCriteria","另一个实体类中对本类的对象属性");

一.延迟加载的概念

   当Hibernate从数据库中加载某个对象时,不加载关联的对象,而只是生成了代理对象,获取使用session中的load的方法(在没有改变lazy属性为false的情况下)获取到的也是代理对象,该对象上的所有属性都为默认值,只有在真正的需要该对象的数据时才创建这个真实的对象,真正的从数据库中加载数据。

二.理解立即加载的概念

  当Hibernate从数据库中加载某个对象时,加载关联的对象,生成的实际对象,获取使用session中的get的方法获取到的是实际对象。

三.为什么要使用延迟加载

  延迟加载策略能避免加载应用程序不需要访问的关联对象,以提高应用程序的性能。

四.立即加载的缺点

Hibernate在查询某个对象时,立即查询与之关联的对象,我们可以看出这种加载策略存在两大不足:

1.select的语句数目太多,需要频繁的访问数据库,会影响查询的性能。

2.在应用程序只需要访问要的对象,而不需要访问与他关联的对象的场景下,加载与之关联的对象完全是多余的操作,这些多余的操作是会占内存,这就造成了内存空间的浪费。

五.什么时候使用延迟加载什么时候使用立即加载

   如果程序加载一个持久化对象的目的是为访问他的属性,则可以采用立即加载。如果程序加载一个持久化对象的目的仅仅是为了获得他的引用,则可以采用延迟加载。

猜你喜欢

转载自blog.csdn.net/mmake1994/article/details/83992696