現象
在使用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實體關係管理雙向關聯的一些思考
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.