JPA的cannot simultaneously fetch multiple bags異常的解決

在springboot中使用jpa,參照 Spring Boot整合jpa,Shiro進(jìn)行權(quán)限管理 寫的程序,在每個(gè)記錄中添加修改用戶,

@ManyToOne(fetch=FetchType.EAGER)
private UserInfo alterUser

在啟動(dòng)程序是,報(bào)

cannot simultaneously fetch multiple bags異常

解決辦法

將@ManyToOne或@ManyToMany的容器由List改為Set

具體原因參照 JPA的cannot simultaneously fetch multiple bags異常的解決
注意文章是2009年發(fā)表的,感覺自己穿越了,基礎(chǔ)知識(shí)真重要。
下面是原文:
cannot simultaneously fetch multiple bags異常是由于持久層實(shí)時(shí)加載太多異同對(duì)象而致。例如用戶登錄時(shí),同步實(shí)時(shí)加載用戶的角色對(duì)象、權(quán)限對(duì)象,而往往這些關(guān)系都是多對(duì)多關(guān)系,就單一列內(nèi)容來看存在重復(fù)的值,從而引起multiple bags。我在網(wǎng)上搜索這類結(jié)果,幾乎都提出一個(gè)解決辦法——采用延遲加載,即fetch=FetchType.LAZY,這樣就束縛了框架的強(qiáng)大功能,也有提過用@IndexColumn解決,但@IndexColumn是Hibernate的東西,不是JPA規(guī)范(下文有討論)。既要實(shí)時(shí)加載,又保證不會(huì)出現(xiàn)主題問題,這就是本文所要探討的。

JPA規(guī)范中,一對(duì)多或多對(duì)多的多方數(shù)據(jù)抓取過來后必須用容器類存,例如Set、List、Map等,初學(xué)者可能沒有對(duì)這個(gè)幾個(gè)容器認(rèn)真研究,隨便拿一個(gè)就用。事實(shí)上這幾個(gè)容器有很大的區(qū)別,本文不具體討論這些容器的區(qū)別和功能,但提一個(gè)特別要注意的區(qū)別——導(dǎo)致本文主題的產(chǎn)生——就是容器內(nèi)是否允許重復(fù)值,那讓們簡單地了解下這此容器的特性:

  • Set:
    Set中不允許存放重復(fù)元素;
    Set中的元素是無序的。

  • List:
    List中可以存放重復(fù)元素;
    List中的元素是一個(gè)有序的集合,可以通過訪問List中的元素。

  • Map:
    Map是以鍵/值存放數(shù)據(jù),因此它有較高的存取性能;
    Map中不允許重復(fù)的鍵,但可以有重復(fù)的值

    有了這些區(qū)別,我們就可以開始尋找主題問題,當(dāng)持久框架抓取一方的對(duì)象時(shí),同時(shí)加載多方的對(duì)象放進(jìn)容器中,多方又可能與關(guān)聯(lián)其它對(duì)象,Hibernate實(shí)現(xiàn)的JPA,默認(rèn)最高抓取深度含本身級(jí)為四級(jí)(它有個(gè)屬性配置是0-3),若多方(第二級(jí))存在重復(fù)值,則第三級(jí)中抓取的值就無法映射,按照這個(gè)道理,就應(yīng)該報(bào)出無法同時(shí)加載多個(gè)包之異常。由于國內(nèi)EJB3.0以后的教材是少而甚少,更沒有較完善的JPA手冊(cè),所以筆者這樣的理解可能會(huì)引起質(zhì)疑,但事實(shí)上,筆者是通過這個(gè)思路解決了問題:

    即@ManyToMany或@OneToMany的Many方此時(shí)一定用Set容器來存放,而不能用List集合。

    不過Hibernate有些功能超越了JPA規(guī)范,它支持真正的List集合,映射集合的方式和以前完全一樣,只不過要新增 @IndexColumn注解,該注解允許你指明存放索引值的字段。但實(shí)際上是創(chuàng)建唯一性索引,抓取多方的結(jié)果也是唯一的,就是上述Set容器不允許重復(fù)元素的道理一樣。

    出現(xiàn)此異常的讀者,先看看自己是不是用了List集合而導(dǎo)致此問題的發(fā)生,若是用Set還出現(xiàn)此問題,則去看Set容器內(nèi)的對(duì)象的類中是不是還有類似問題。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 在一個(gè)方法內(nèi)部定義的變量都存儲(chǔ)在棧中,當(dāng)這個(gè)函數(shù)運(yùn)行結(jié)束后,其對(duì)應(yīng)的棧就會(huì)被回收,此時(shí),在其方法體中定義的變量將不...
    Y了個(gè)J閱讀 4,436評(píng)論 1 14
  • 2018年本科畢業(yè),這是我2015年的一篇習(xí)作,那時(shí)還堅(jiān)持寫些東西,雖然稚嫩,但是總有自己的思考。謹(jǐn)以此獻(xiàn)給我的母...
    唯軼閱讀 412評(píng)論 1 1
  • 今日觀點(diǎn): 在管理上,具體執(zhí)行時(shí)需要注意兩點(diǎn): 第一,一個(gè)上級(jí)原則。 一個(gè)領(lǐng)導(dǎo)可以有很多下屬,但是一個(gè)員工,只能有...
    楊雪雪閱讀 286評(píng)論 0 2
  • 不是我的錯(cuò),請(qǐng)?jiān)徫?。我真的很抱歉?我是11月26號(hào),周四辭的職。周五、周六、周日放縱了三天。周日晚上,開始瘋狂...
    是京京呀閱讀 215評(píng)論 0 1
  • 今天回到永川,本來想著很久沒有回來了,下周又要繼續(xù)加班,就回來看看爸爸媽媽。今天,下了高鐵,就是媽媽過來接我的,于...
    小米雨路閱讀 112評(píng)論 0 0