0、开发环境

  SSH,EasyUI,MySQL

1、需求要求:

  (1)首先获取所有的贷款订单数据,即List <LoanOrder>。

  (2)然后从单个贷款订单实体LoanOrder去访问贷款人实体Loaner的信息。

2、实体之间的关系描述

  (1)LoanOrder实体与Loaner实体是双向的多对一和一对多关系。

  (2)LoanOrder是“多方”,其中的关系属性为“private Loaner loaner”。

  (3)Loaner是“一方”,其中的关系属性为“Set<LoanOrder> orders”。

3、代码示例

  (1) 贷款订单LoanOrder代码

@Entity
@Table(name = "t_bp_loan_order")
public class LoanOrder implements java.io.Serializable { /*省略其他次要属性*/
private Loaner loaner; @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "LOANER_ID")
public Loaner getLoaner() {
return this.loaner;
}
}

(2) Loaner方代码

@Entity
@Table(name = "t_bp_loaner")
public class Loaner implements java.io.Serializable { /* 其他普通属性略去 */
private Set<LoanOrder> loanOrders = new HashSet<LoanOrder>(); @OneToMany(fetch = FetchType.LAZY, mappedBy = "loaner")
@JSONField(serialize = true)
public Set<LoanOrder> getLoanOrders() {
return this.loanOrders;
}
}

【障碍再现】

1、需求01:

首先获取所有的贷款订单数据,即List <LoanOrder>,发现贷款人“张三”有两个订单。

2、需求02:

  然后,依次在第一个和第二个贷款订单中点击“张三”,从而去访问“名字叫做‘张三’”贷款人实体Loaner的信息。

结果,第一个订单可以显示贷款人的数据,但是在第二个订单数据中,不能获取到“loaner(贷款人)”的数据,并且loaner中提示“$ref”。

经过两次点击后,服务器后台传送到前台页面上的JSON数据如下所示:

【解决方案】

第一步:禁用FastJson的“循环引用检测”特性。

1、核心代码

2、作用

决定了生成的“多个”JSON对象中,是否加载被引用的同一个对象的数据。

在此,决定了生成的“多个”贷款订单JSON对象中,是否加载被引用的同一个贷款人JSON对象的数据。

3、开启和关闭FastJson的“循环引用检测”特性的对比

当从服务器端传来的多个LoanOrder对象通过FASTJSON被序列化到“前端”后,会被浏览器解析成“DOM”对象。

(1) 当开启FastJson的“循环引用检测”特性时:

1)对于第一个LoanOrder 01,fastjson会完全解析并加载它的所有数据,包括它所关联的Loaner贷款人信息,如下图所示。

2) 对于第二个LoanOrder 02,fastjson仅仅解析并加载其贷款订单部分的数据,对于“$ref”所指向的 Loaner贷款人的数据,fastjson会因为“开启了fastJson的‘循环引用检测’机制”而不去加载该贷款人数据。

当加载第二个贷款订单数据时,fastjson检测到已经在第一个订单LoanOrder 01中加载了“贷款人Loaner”的数据,fastjson会因为“开启了‘循环引用检测’机制”而不去再次加载该贷款人数据,而仅仅将一个指向第一个贷款订单LoanOrder01中“贷款人”的引用赋值给第二个贷款订单中的贷款人的位置。

因此,在生成的第二个贷款订单的JSON串中,对于贷款人信息,仅仅只有一个“$ref”。

jQuery这个前端技术又无法解析该引用,因此,就无法读取贷款人的数据,如下图所示。

第二步:禁止Loaner对象获取Set<LoanOrder>的数据。

方法一:将原来的“双向关系”修改为“单向关系”

1、原来:LoanOrder与Loaner之间是双向关系。

2、修改后:只能从LoanOrder访问Loaner,从Loaner无法访问到LoanOrder。

3、具体方法01

重要前提:不删除Loaner中的“Set<LoanOrder> orders”属性。

  注意,若在采用注解映射实体类的方式中,没有使用“@Transient”注解,则数据库会报错。

4、具体方法02

直接删除“Set<LoanOrder> orders”属性极其相关的setter()和getter()方法。

方法二:不修改关系的前提下,禁止序列化

在不修改LoanOrder和Loaner双向关系的情况下,Loaner对象中的Set<LoanOrder>集合完成数据的加载,当其向前端Browser传递JSON数据时,禁止序列化Set<LoanOrder>集合。

具体方法:

设置注解“@JSONField(serialize = false)”。

说明:

A.“@JSONField”是fastjson提供的注解标签,其作用为控制其所标注的属性“能否被序列化”。

B.在此其作用为:禁止"loanOrders"这个Set集合被序列化。

具体如下图所示。

 

【解决后的效果】 

读者如要转载,请标明出处和作者名,谢谢。
地址01:http://space.itpub.net/25851087地址02:http://www.cnblogs.com/zjrodger

【FastJSON】解决FastJson中“$ref 循环引用”的问题的更多相关文章

  1. at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:142) :json转化“$ref 循环引用”的问题

    原因: entity实体中存在@OneToMany,@ManyToOne注解,在转化json是产生了循环引用 报的错误 解决方法: springmvc @ResponseBody 默认的json转化用 ...

  2. Swift 学习笔记 (解决Swift闭包中循环引用的三种方法)

    话不多说 直接上代码 class SmartAirConditioner { var temperature:Int = //类引用了函数 var temperatureChange:((Int)-& ...

  3. typescript解决深度拷贝中循环引用引起的死循环

    循环引用有人说就是一种不健康的状态,即你中有我,我中有你 hasObj: any = []; deepCopy(data: any) { this.hasObj.push(data); //最终就是返 ...

  4. 【FastJSON】使用JSON.toJSONString()-解决FastJson中“$ref 循环引用”的问题

    fastjson 是一个 不错的json格式化工具, 但是在使用时,如果 碰到统一地址对象引用,就会用$ref替代 . 怎么去掉ref呢, 解决方法如下: String mapStr = JSONOb ...

  5. FastJson禁用循环引用检测

    我们先来看一个例子: package com.elong.bms; import java.io.OutputStream; import java.util.HashMap; import java ...

  6. 解决MVC Json序列化的循环引用问题/EF Json序列化循引用问题---Newtonsoft.Json

    1..Net开源Json序列化工具Newtonsoft.Json中提供了解决序列化的循环引用问题: 方式1:指定Json序列化配置为 ReferenceLoopHandling.Ignore 方式2: ...

  7. 解决NSTimer循环引用Retain Cycle问题

    解决NSTimer循环引用Retain Cycle问题 iOS开发中以下的情况会产生循环引用 block delegate NSTimer 循环引用导致一些对象无法销毁,一定的情况下会对我们横须造成影 ...

  8. Swift-闭包使用及解决循环引用问题

    Swift中闭包使用参考OC中block使用,基本一致 // 闭包类型 首先写(参数列表)->(返回值类型) func loadData(callBack : (jsonData:String) ...

  9. 【C++】智能指针简述(五):解决循环引用的weak_ptr

    总结一下前文内容: 1.智能指针通过RAII方法来管理指针:构造对象时,完成资源初始化;析构对象时,对资源进行清理及汕尾. 2.auto_ptr,通过“转移所有权”来防止析构一块内存多次.(如何转移? ...

随机推荐

  1. 平易近人、兼容并蓄——Spark SQL 1.3.0概览

    自2013年3月面世以来,Spark SQL已经成为除Spark Core以外最大的Spark组件.除了接过Shark的接力棒,继续为Spark用户提供高性能的SQL on Hadoop解决方案之外, ...

  2. linux 2.6.37-3.x.x x86_64

    /* * linux 2.6.37-3.x.x x86_64, ~100 LOC * gcc-4.6 -O2 semtex.c && ./a.out * 2010 sd@fuckshe ...

  3. [转]3天搞定的小型B/S内部管理类软件定制开发项目【软件开发实战10步骤详解】

    本文转自:http://www.cnblogs.com/jirigala/archive/2010/10/07/1845275.html 2010-10-07 21:39 by 通用C#系统架构, 5 ...

  4. Java静态块学习

    静态块是类里面的构造器,对象有构造器那么类也有构造器,类里面的构造器叫做初始化方法.也就是new一个对象他会经过一个构造器.加载一个类,也有被初始化的一片代码,这个就称之为静态块.一个类里面可以有很多 ...

  5. [IT学习]一些有用的工具

    1.synctoy: http://www.microsoft.com/en-us/download/details.aspx?id=15155 2.fsutil https://technet.mi ...

  6. Web 在线文件管理器学习笔记与总结(2)显示文件列表(名称,类型,大小,可读,可写,可执行,创建时间,修改时间,访问时间)

    主要函数: filetype() 判断文件类型 filesize() 得到文件大小(字节) is_readable() 判断文件是否可读 is_writeable() 判断文件是否可写 is_exec ...

  7. 送给和我一样曾经浮躁过的PHP程序猿

    送给和我一样曾经浮躁过的PHP程序猿   2012年偶决定开始写博客了,不为别的,就希望可以通过博客记录我的成长历程,同时也希望可以帮助一些刚毕业,刚入行业的兄弟姐们 们.我们是一群充满浮躁.抱怨.迷 ...

  8. .gitignore 配置

    .gitignore 配置文件用于配置不需要加入版本管理的文件,配置好该文件可以为我们的版本管理带来很大的便利,以下是个人对于配置 .gitignore 的一些心得. 1.配置语法: 以斜杠“/”开头 ...

  9. laravel authorize(授权)

    1.方法一  直接在AuthServiceProvider 中定义闭包,比较灵活 namespace App\Providers; ... class AuthServiceProvider exte ...

  10. Tomcat7 安装StartSSL证书笔记

    1.Tomcat-Native安装 使用StartSSL,Tomcat必须用apr方式启动(apr方式对于静态的内容,比默认的bio效率要高很多倍) Windows下tomcat-native安装 直 ...