Hibernate general serialization scheme to avoid delay loading problem and serialization of entire database to client

Source: Internet
Author: User
Tags json modifier serialization throwable

The process of using ajax:hibernate Entity => json, Flex remoteobject:hibernate Entity => ActionScript object frequently encounters the following problems:

Problem:

1.Hibernate throws Lazyinitializationexception If session is closed when a deferred-load property access is encountered

In the case of One-to-many in 2.Hibernate, if there is no control in serialization, the entire database may be serialized

3. Excessive use of dto/valueobject to solve this problem.

Solution:

Generates a dynamic proxy for the entity object, blocks the Getxxxx () method, and if you are accessing a deferred-loading property, return null instead of throwing the lazyinitializationexception, recursively generating the code for the property, Serialization automatically stops whenever a property is encountered that does not delay loading. Avoid serializing the entire entity, causing problems that might serialize the entire database.

Similar solutions:

Hibernateconverter in Dwr, when serialized, a property that encounters a deferred load automatically stops the convert operation. and Hibernatebeanserializer is once and for all, regardless of object => JSON can work.

Use Use cases:

Java code

//role为原始对象
role = (Role)roleDao.getById(new Long(1));
//生成的动态代理proxyRole,访问延迟加载的属性将return null
Role proxyRole = (Role)new HibernateBeanSerializer<Role>(role).getProxy();
assertNotNull(role.getResource());
assertNull(proxyRole.getResource()); //延迟加载,为null

Hibernate.initialize(role.getResource()); //抓取进来
assertNotNull(proxyRole.getResource()); //不为null

Source.

Java code

package cn.org.rapid_framework.util;





import Java.lang.reflect.Modifier;


import java.util.ArrayList;


import java.util.Collection;


import Java.util.LinkedHashMap;


import Java.util.LinkedHashSet;


import java.util.List;


import Java.util.Map;


import Java.util.Set;





import Org.aopalliance.intercept.MethodInterceptor;


import org.aopalliance.intercept.MethodInvocation;


import org.hibernate.Hibernate;


import org.hibernate.collection.PersistentCollection;


import Org.hibernate.proxy.HibernateProxy;


import org.springframework.aop.framework.ProxyFactory;


import org.springframework.util.StringUtils;





/**


* is used for serialization of Hibernate Object, the property that accesses the deferred load does not throw a lazyinitializationexception and returns a null value.


* Use:


* &lt;pre&gt;


* Blog Proxyblog = new Hibernatebeanserializer (blog). GetProxy ();


* &lt;/pre&gt;


* @author Badqiu


* @param &lt;T&gt;


  */


public class Hibernatebeanserializer &lt;T&gt; {


T proxy = null;


  /**


  */


public Hibernatebeanserializer (T object,string ... excludesproperties) {


if (object = = null) {


This.proxy = null;


}else {


Proxyfactory pf = new Proxyfactory ();


Pf.settargetclass (Object.getclass ());


Pf.setoptimize (TRUE);


Pf.settarget (object);


Pf.setproxytargetclass (TRUE);


Pf.setopaque (TRUE);


Pf.setexposeproxy (TRUE);


pf.setprefiltered (TRUE);


Hibernatebeanserializeradvice beanserializeradvice = new Hibernatebeanserializeradvice ();


beanserializeradvice.setexcludesproperties (excludesproperties);


Pf.addadvice (Beanserializeradvice);





this.proxy = (T) pf.getproxy ();


  }


  }





public T GetProxy () {


return this.proxy;


  }





static Private class Hibernatebeanserializeradvice implements Methodinterceptor {


Private string[] excludesproperties = new String[0];


public string[] Getexcludesproperties () {


return excludesproperties;


  }


public void Setexcludesproperties (string[] excludesproperties) {


this.excludesproperties = Excludesproperties = null? New string[0]: excludesproperties;


  }


public Object Invoke (Methodinvocation mi) throws Throwable {


String propertyname = Getpropertyname (Mi.getmethod (). GetName ());


Class returntype = Mi.getmethod (). Getreturntype ();





if (propertyname = = null) {


return Mi.proceed ();


   }


if (! Hibernate.ispropertyinitialized (Mi.getthis (), PropertyName)) {


return null;


   }


if (Isexclude (MI, propertyname)) {


return null;


   }





Object returnvalue = Mi.proceed ();


return Processreturnvalue (ReturnType, returnvalue);


  }





private Object Processreturnvalue (Class returntype, Object returnvalue) {


if (returnvalue = null)


return null;


if (returntype!= null &amp;&amp; modifier.isfinal (Returntype.getmodifiers ())) {


return returnvalue;


   }


//this might is a lazy-collection so we need to double check


if (! Hibernate.isinitialized (returnvalue)) {


return null;


   }





//this is Hibernate Object


if (returnvalue instanceof hibernateproxy) {


return to New Hibernatebeanserializer (returnvalue). GetProxy ();


}else if (returnvalue instanceof persistentcollection) {


if (Returntype.isassignablefrom (Map.class)) {


Map proxymap = new Linkedhashmap ();


map map = (map) returnvalue;


set&lt;map.entry&gt; entryset = Map.entryset ();


for (Map.entry entry:entryset) {


Proxymap.put (Entry.getkey (), New Hibernatebeanserializer (Entry.getvalue ()));


    }


return proxymap;


   }





Collection proxycollection = null;


if (Returntype.isassignablefrom (Set.class)) {


proxycollection = new Linkedhashset ();


}else if (Returntype.isassignablefrom (List.class)) {


proxycollection = new ArrayList ();


}else {


return returnvalue;


   }





for (Object o: (Collection) returnvalue) {


Proxycollection.add (new Hibernatebeanserializer (O). GetProxy ());


   }


return proxycollection;


}else {


return returnvalue;


   }


  }





Private Boolean isexclude (methodinvocation mi, String PropertyName)


throws Throwable {





for (String excludepropertyname:excludesproperties) {


if (propertyname.equals (Excludepropertyname)) {


return true;


   }


   }





return false;


  }





private static string Getpropertyname (String methodname) {


String propertyname = null;


if (Methodname.startswith ("get")) {


propertyname = methodname.substring ("Get". Length ());


}else if (Methodname.startswith ("is")) {


PropertyName = Methodname.substring ("is". Length ());


}else if (Methodname.startswith ("set")) {


propertyname = methodname.substring ("set". Length ());


   }


return propertyname = = null? Null:StringUtils.uncapitalize (PropertyName);


  }


  }


}

Another of these classes is part of the Rapid-framework, and the v2.0 version of Flex RemoteObject will use this approach. The preview version is about to be released

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.