Json-lib jQuery ext hibernate together with the use of an endless loop problem resolution

An error

net.sf.json.JSONException: There is a cycle in the hierarchy!
	net.sf.json.util.CycleDetectionStrategy$StrictCycleDetectionStrategy.handleRepeatedReferenceAsObject(CycleDetectionStrategy.java:97)
	net.sf.json.JSONObject._fromBean(JSONObject.java:833)
	net.sf.json.JSONObject.fromObject(JSONObject.java:168)
	net.sf.json.AbstractJSON._processValue(AbstractJSON.java:265)
	net.sf.json.JSONArray._processValue(JSONArray.java:2514)
	net.sf.json.JSONArray.processValue(JSONArray.java:2539)
	net.sf.json.JSONArray.addValue(JSONArray.java:2526)
	net.sf.json.JSONArray._fromCollection(JSONArray.java:1057)
	net.sf.json.JSONArray.fromObject(JSONArray.java:123)
	net.sf.json.AbstractJSON._processValue(AbstractJSON.java:237)
	net.sf.json.JSONObject._processValue(JSONObject.java:2808)
	net.sf.json.JSONObject.processValue(JSONObject.java:2874)
	net.sf.json.JSONObject.setInternal(JSONObject.java:2889)
	net.sf.json.JSONObject.setValue(JSONObject.java:1577)
	net.sf.json.JSONObject._fromBean(JSONObject.java:934)
	net.sf.json.JSONObject.fromObject(JSONObject.java:168)
	net.sf.json.AbstractJSON._processValue(AbstractJSON.java:265)
	net.sf.json.JSONObject._processValue(JSONObject.java:2808)
	net.sf.json.JSONObject.processValue(JSONObject.java:2874)
	net.sf.json.JSONObject.setInternal(JSONObject.java:2889)
	net.sf.json.JSONObject.setValue(JSONObject.java:1577)
	net.sf.json.JSONObject._fromBean(JSONObject.java:934)
	net.sf.json.JSONObject.fromObject(JSONObject.java:168)
	net.sf.json.AbstractJSON._processValue(AbstractJSON.java:265)

 

 

 

CGLIB to use hibernate POJO objects in the domain dynamic agent, to achieve its magic, but to JSON serialization brought trouble, not because JSON serialize the property of lazy. There are four ways to solve the problem of hibernate serialization

  1. domain类实现JSONString接口
  2. Establish JsonConfig instance, and configure the attribute exclusion list
  3. 用属性过滤器
  4. Write a custom JsonBeanProcessor

1. JSONString implement the interface is the most invasive method

public class Person implements JSONString {
   private String name;
   private String lastname;
   private Address address;
 
   // getters & setters
 
   public String toJSONString() {
      return "{name:'"+name+"',lastname:'"+lastname+"'}";
   }
}
<span id="more-724"></span>

2. The second method, the properties include and exclude the need for convenient add and delete instances by jsonconfig

public class Person {
   private String name;
   private String lastname;
   private Address address;
 
   // getters &amp; setters
}
 
JsonConfig jsonConfig = new JsonConfig();
jsonConfig.setExclusions( new String[]{ "address" } );
Person bean = /* initialize */;
JSON json = JSONSerializer.toJSON( bean, jsonConfig );

NOTE: This method does not distinguish between target class, that is, if there exists among the two bean "address" attribute, then the use of this method, the bean properties of the two address will be excluded

3. propertyFilter simultaneously allows to exclude class attributes and control, this control may be bi-directional, may be applied to the string to java objects json

public class Person {
   private String name;
   private String lastname;
   private Address address;
 
   // getters &amp; setters
}
 
JsonConfig jsonConfig = new JsonConfig();
jsonConfig.setJsonPropertyFilter( new PropertyFilter(){
   public boolean apply( Object source, String name, Object value ){
      // return true to skip name
      return source instanceof Person &amp;&amp; name.equals("address");
   }
});
Person bean = /* initialize */;
JSON json = JSONSerializer.toJSON( bean, jsonConfig )

4. Finally look JsonBeanProcessor, and in this way to achieve JsonString very similar return on behalf of a legal JSONOBJECT original domain class

public class Person {
   private String name;
   private String lastname;
   private Address address;
 
   // getters &amp; setters
}
 
JsonConfig jsonConfig = new JsonConfig();
jsonConfig.registerJsonBeanProcessor( Person.class,
   new JsonBeanProcessor(){
      public JSONObject processBean( Object bean, JsonConfig jsonConfig ){
         if( !(bean instanceof Person) ){
            return new JSONObject(true);
         }
         Person person = (Person) bean;
         return new JSONObject()
            .element( "name", person.getName() )
            .element( "lastname", person.getLastname() );
      }
});
Person bean = /* initialize */;
JSON json = JSONSerializer.toJSON( bean, jsonConfig );

Carefully checked and found that the wrong foreign key primary hibernate, and later wanted to look at the source code under json, json found that the trouble did not get the source code, or the old way decompile Chou Chou and found JSONArray different judgments obtained under call the appropriate type of method,

if (object instanceof Collection)
    return _fromCollection((Collection)object, jsonConfig);

And I got that from hibernate list, so to call the _fromCollection method, and the method which found a problem: this method will continue to open the entity attributes, until there are no, and my ContactGroup there are two properties with to associate themselves

private Set contactGroups = new HashSet(0);
private Set contactGroupPersons = new HashSet(0);


That is the primary foreign key itself is associated with a cycle of death, then how can we not let him do this happens, there should be a place which terminates the loop configuration parameters of it, you can find that, jsonConfig, Oh, config should be configured bar parameters, see reference JsonConfig huge number attribute, PropertyFilter bit dizzy, not to mention, looked waited a long time, a property found PropertyFilter, PropertyFilter an interface, the code is as follows:

public interface PropertyFilter
{

public abstract boolean apply(Object obj, String s, Object obj1);
}

That I can be filtered out by this method in the corresponding List property returns true as long as it can be filtered out, ......, jeopardy ...... we rewrite this method:

JsonConfig cfg = new JsonConfig();
    cfg.setJsonPropertyFilter(new PropertyFilter()
    {
         public boolean apply(Object source, String name, Object value) {
           if(name.equals("contactGroups")||name.equals("contactGroupPersons")) {
             return true;
           } else {
             return false;
          }
        }
       });

The resulting entity bean hibernate in contactGroups and contactGroupPersons filtered out to OK!

Then call JSONArray.fromObject (mychildren, cfg); mychildren hibernate is returned list.

Okar, thus, continue to do the project ......

Reproduced in: https: //my.oschina.net/usenrong/blog/197860

Guess you like

Origin blog.csdn.net/weixin_34292959/article/details/92028898