对JPA实体关系管理双向关联的一些思考
来源:互联网 发布:阿里云网站上线 编辑:程序博客网 时间:2024/06/06 13:02
现象
在使用JPA进行实体关系管理的时候,会产生无限循环的情况,如果使用fastjson来进行序列化,则表现形式如下:{ "address":{ "id":63, "name":"1address name", "person":{"$ref":".."}, "zipCode":"ZipCode01" }, "firstName":"0firstName", "id":69, "lastName":"0lastName"},{ "address":{ "id":64, "name":"2address name", "person":{"$ref":".."}, "zipCode":"ZipCode11" }, "firstName":"1firstName", "id":70, "lastName":"1lastName"}
重点是
address.person
的值:{"$ref":".."}
如果你用的不是fastjson(它默认会检查该对象是否已经存在在json文本中)而是其他一些json类库,比如jackson,则会抛出java.lang.StackOverflowError
异常(无限循环产生的栈溢出所导致).
但是,哪怕你用的是fastjson,你也无法用js来解析{"$ref":".."}
.解决思路
- 使用fastjson自带的
JSON.toJSONString(page,SerializerFeature.DisableCircularReferenceDetect)
- 优点:解决快速
- 缺点:
- 序列化后的json文本包含太多不需要的信息,冗杂程度太高
- 方式太死板,没有相应的注解来实现(jackson有一个),接口只能返回String类型了.
重新设计实体关系,尽量避免双向关联,使用RESTful进行接口的暴露.(举个例子来说)
- 优点:逻辑清晰,结构更合理
- 缺点:
- 对老代码改动较大.
- 实现较复杂,要对整体业务逻辑有清晰的认识.
实体类Person
public class Person { private String name; @Id @GeneratedValue private Long id; @ManyToMany @JoinColumn(name = "address_id") private List<Address> addresses; // ...... getter and setter}
实体类Address
public class Address { @Id @GeneratedValue private Long id; private String name; private String zipCode; // ...... getter and setter}
两个实体类之间的关系为Many Person To Many Address,只在Person实体类中进行关系的配置,避免双向关联.
下面举例说明使用RESTful来对资源进行访问的情况.
对于Person:
- 1 查询所有Person:
/persons
- 2 查询某一个Person:
/persons/{person_id}
- 3 查询某一个Person的所有Address:
/persons/{person_id}/addresses
4 查询某一个Person的某一个Address:
/persons/{person_id}/addresses/{address_id}
如果要查询一个Address有几个Person:
/persons?address.id=xxx
(带分页,自己设置pageSize)
对于Address:
- 1 查询所有Address:
/addresses
- 2 查询某一个Address:
/addresses/{address_id}
以上是Person和Address的一些简单接口.其中粗体部分为关联查询.
设计的思路就是要尽量避免双向关联,然后把Person作为一个资源,把Address作为Person的一个子资源或者属性.
上述Person中的1 2 将Address作为了属性,查询时可以通过参数传递进去.而上述Person中的3 4 两个接口则将Address作为一个子资源进行管理.如果要用Address来作为一个资源反查Person怎么办?
在一个Address管理页面,需求要求列出某一个住址下的Person:- 点击某一项:
Address发起/persons?address.id=xxx
请求,取得List<Person>
. - 默认显示:
在controller层对/persons?address.id_in=xxx1,xxx2,xxx3
接口的返回值进行处理,取得List<Address>
和其对应的List<Person>
- 使用fastjson自带的
总结
尽量避免双向关联,使用更合理的API设计方式,合理区分子资源和属性.
大大减少数据库压力!
- 对JPA实体关系管理双向关联的一些思考
- jpa双向多对多关联关系
- jpa 双向一对多,多对一关联关系
- JPA映射关联关系-双向多对多
- JPA的双向一对多和双向一对一关联关系
- jpa双向一对一关联关系
- JPA学习笔记-映射双向多对多的关联关系
- JPA学习笔记-映射双向一对多的关联关系
- JPA学习笔记-映射双向一对一的关联关系
- 对双向相关bean的一些思考
- JPA实体关联关系映射之概述
- JPA映射关联关系-双向一对多
- JPA映射关联关系-双向一对一
- jpa的关联关系
- JPA多对多双向关联实例
- JPA多对多双向关联
- JPA中的多对多双向关联、级联操作、关系维护、延迟加载
- JPA学习笔记(10)——映射双向多对多关联关系
- hiho第一周A+B各种语言版本(内容来自hiho)
- tabhost相关报错
- 向良好进军!
- plugin & hook
- find命令
- 对JPA实体关系管理双向关联的一些思考
- Android 开发者的 RxJava 详解 - 作者:扔物线
- 欢迎使用CSDN-markdown编辑器
- hrbustOJ 1787 New Fibonacci Number (矩阵快速幂+欧拉公式降幂)
- Mac os下安装mysql
- 最大子序列
- SpringMVC实战(二)-运行原理
- 支付宝集成问题
- AutocAD二次开发出错:检索 COM 类工厂中 CLSID 为 {} 的组件时失败