1. 程式人生 > >對JPA實體關係管理雙向關聯的一些思考

對JPA實體關係管理雙向關聯的一些思考

  • 現象
    在使用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>
  • 總結
    儘量避免雙向關聯,使用更合理的API設計方式,合理區分子資源和屬性.
    大大減少資料庫壓力!

相關推薦

JPA實體關係管理雙向關聯一些思考

現象 在使用JPA進行實體關係管理的時候,會產生無限迴圈的情況,如果使用fastjson來進行序列化,則表現形式如下: { "address":{ "id":63,

QQA: Hibernate 為什麼需要手工管理雙向關聯

Hibernate/JPA 中如果兩個 Entity 之間的關聯是雙向的(不論是 @ManyToMany、 @OneToMany 還是 @OneToOne),都需要手動管理關聯,為什麼? 呼叫 entityManager.persist 儲存物件時 Hibernate/JPA 不會直接執行 SQL,而會等到

Hibernate 對映關係 ---Many2Many 雙向關聯

以Student和Course為例,一個學生可以選多門課程,一門課程也可以被多個學生選取; 持久化類Student: [java]  view plain copy

Hibernate 對映關係 ---One2Many 雙向關聯

一種商品類別下有多個商品,多個商品對應同一個商品類別,這種關係就是一對多雙向關聯。   商品類: [java]  view plain copy p

客戶關係管理系統的一些心得和感受分享

這個專案呢,感覺還挺難哦,主要是通過這個系統完成對客戶基本資訊、聯絡人資訊、客戶服務資訊、公司銷售情況、產品、庫存的充分共享和規範化管理;在客戶將要流失時系統及時預警,以便銷售人員及時採取措施,降低損失。並通過系統提供

JPA實體關係對映

實體關係是指實體與實體之間的關係,從方向上分為單向關聯和雙向關聯,從實體數量上分為一對一、一對多、多對多等。對於任何兩個實體,都要從這兩個方面區分它們之間的關係。 單向關聯是一個實體中引用了另外一個實體,也即通過一個實體可以獲取另一個實體物件的引用;雙向關聯是兩個實體之間

研發團隊裡技術分享的一些思考

  這是我最近看到的一篇關於公司技術分享的比較好的文章  就粘過來大家一起學習吧 https://www.iteye.com/blog/aoyouzi-2342659 分享目的 做任何事情,要明確目的,才能清晰、順利實施。目的包括這件事能幫大家帶來什麼、能給公司帶來什麼、預期結果是什麼、成

CROS OPTIONS預檢請求的一些思考

前後端分離模大勢所趨,跨域問題更是老生常談。 問題背景: > 瀏覽器最基本的安全規範-**同源策略**。所謂同源是指域名、協議、埠相同。不同源的瀏覽器指令碼(javascript、ActionScript、canvas)在沒有明確授權的情況下,不能讀寫對方的資源。 CORS就是w3c和瀏覽器廠商為解決跨

Hibernate,關係對映的多一單向關聯、多雙向關聯、一對一主鍵關聯、一對一外來鍵關聯、多關係關聯

2018-11-10  22:27:02開始寫   下圖內容ORM、Hibernate介紹、hibername.cfg.xml結構:     下圖內容hibernate對映檔案結構介紹   下圖內容hibernate

JPA中多多表關係的刪除操作,如何刪除放棄維護關聯關係的一方和中間表的紀錄

資料庫中的表 使用者表:在配置實體類的時候放棄了維護關聯關係的權利 角色表: 中間表: 需求:刪除t_user表中的user_id 為1的使用者,並刪除相關的中間表紀錄。 程式碼: @Test public

JPA實體關聯關係對映之概述

    一、簡介 首先來說關聯關係是面向物件分析,面向物件設計最重要的部分,JPA是完全可以通過對映來簡化資料持久化到資料,和Hibernate一樣,JPA的關聯關係也分為兩種,一種是單向關聯,一種是雙向關聯: 單向關聯:只需要單向訪問關聯端,比如說:我們只能通過某一學期訪

JPAJPA中的多雙向關聯

如果要搭建JPA開發環境,請從JPA第一篇部落格看起。 下面的例子以老師和學生的例子進行多對多關係的編碼講解。 1、Student.java中的程式碼 package cn.sunft.bean; import java.util.HashSet; import j

hibernate的映射之四(多雙向關聯)

als oot bean odi 生成 指定 數據庫方言 映射文件 格式化sql Many-to-Many 多對多的映射可以使用一組Java集合不包含任何重復的元素來實現。我們已經看到了Hibernate如何設置映射集合。 集(SET)被映射到與映射表中<set&g

Hibernate,關系映射的多一單向關聯、多雙向關聯、一對一主鍵關聯、一對一外鍵關聯、多多關系關聯

nat 延遲加載 alt ima orm 雙向關聯 映射文件 結構 spa 2018-11-10 22:27:02開始寫 下圖內容ORM、Hibernate介紹、hibername.cfg.xml結構: 下圖內容hibernate映射文件結構介紹

一對多|多關係 ---- Hibernate之關聯對映

敘:hibernate中的關聯對映存在一對多多對一關係和多對多關係;本章節電蟲就關聯對映的一對多多對一關係進行學習和總結記錄; Hibernate的關聯對映之“一對多|多對一”關係 準備工作 需要有兩個實體類以及實體類所對應的對映檔案,由於之前建立

Hibernate多多的雙向關聯

Hibernate多對多關係:可以看作是兩個一對多,比如書籍與類別,書籍可以有多個類別,類別下可以有多本書籍 既然多對多可以看作兩個一對多,那麼維護只能交給一方進行維護,比如我做級聯新增時,如果雙方都維護,就會造成資料重複 準備: SessionFactoryU

JPA中多多表關係的刪除操作,如何只刪除一方和中間表的紀錄

資料庫中的表 使用者表: 角色表: 中間表: 需求:刪除t_user表中的user_id 為1的使用者,並刪除相關的中間表紀錄。 程式碼: @Test public void testRemove() {

MyEclipse開發教程:使用REST Web Services管理JPA實體(三)

MyEclipse 線上訂購年終抄底促銷!火爆開搶>> MyEclipse最新版下載 使用REST Web Services來管理JPA實體。在逆向工程資料庫表後生成REST Web服務,下面的示例建立用於管理部落格條目的簡單Web服務。你將學會: 利用資料庫逆向工程開

MyEclipse開發教程:使用REST Web Services管理JPA實體(二)

MyEclipse 線上訂購年終抄底促銷!火爆開搶>> MyEclipse最新版下載 使用REST Web Services來管理JPA實體。在逆向工程資料庫表後生成REST Web服務,下面的示例建立用於管理部落格條目的簡單Web服務。你將學會: 利用資料庫逆向工程開

MyEclipse開發教程:使用REST Web Services管理JPA實體(一)

MyEclipse 線上訂購年終抄底促銷!火爆開搶>> MyEclipse最新版下載 使用REST Web Services來管理JPA實體。在逆向工程資料庫表後生成REST Web服務,下面的示例建立用於管理部落格條目的簡單Web服務。你將學會: 利用資料庫逆向工程開