EJB持久層cannot simultaneously fetch multiple bags異常的解決

病理特徵:Caused by: org.hibernate.HibernateException: cannot simultaneously fetch multiple bags,html

    堆棧信息:org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'initSystemDataBySpringListeren': Injection of resource fields failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'service': Injection of resource fields failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'assistantDao': Injection of resource fields failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [spring-core-config.xml]: Invocation of init method failed; nested exception is org.hibernate.HibernateException: cannot simultaneously fetch multiple bagsspring

     ......session

     cannot simultaneously fetch multiple bags異常是因爲持久層實時加載太多異同對象而致。例如用戶登陸時,同步實時加載用戶的角色對象、權限對象,而每每這些關係都是多對多關係,就單一列內容來看存在重複的值,從而引發multiple bags。我在網上搜索這類結果,幾乎都提出一個解決辦法——採用延遲加載,即fetch=FetchType.LAZY,這樣就束縛了框架的強大功能,也有提過用@IndexColumn解決,但@IndexColumn是Hibernate的東西,不是JPA規範(下文有討論)。既要實時加載,又保證不會出現主題問題,這就是本文所要探討的。框架

    JPA規範中,一對多或多對多的多方數據抓取過來後必須用容器類存,例如Set、List、Map等,初學者可能沒有對這個幾個容器認真研究,隨便拿一個就用。事實上這幾個容器有很大的區別,本文不具體討論這些容器的區別和功能,但提一個特別要注意的區別——致使本文主題的產生——就是容器內是否容許重複值,那讓們簡單地瞭解下這此容器的特性:性能

Set:fetch

_Set中不容許存放重複元素;
_Set中的元素是無序的。
spa

List:hibernate

_List中能夠存放重複元素;
_List中的元素是一個有序的集合,能夠經過訪問List中的元素。
xml

Map:htm

_Map是以鍵/值存放數據,所以它有較高的存取性能;
_Map中不容許重複的鍵,但能夠有重複的值

    有了這些區別,咱們就能夠開始尋找主題問題,當持久框架抓取一方的對象時,同時加載多方的對象放進容器中,多方又可能與關聯其它對象,Hibernate實現的JPA,默認最高抓取深度含自己級爲四級(它有個屬性配置是0-3),若多方(第二級)存在重複值,則第三級中抓取的值就沒法映射,按照這個道理,就應該報出沒法同時加載多個包之異常。因爲國內EJB3.0之後的教材是少而甚少,更沒有較完善的JPA手冊,因此筆者這樣的理解可能會引發質疑,但事實上,筆者是經過這個思路解決了問題:

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

    不過Hibernate有些功能超越了JPA規範,它支持真正的List集合,映射集合的方式和之前徹底同樣,只不過要新增 @IndexColumn註解,該註解容許你指明存放索引值的字段。但其實是建立惟一性索引,抓取多方的結果也是惟一的,就是上述Set容器不容許重複元素的道理同樣。

    出現此異常的讀者,先看看本身是否是用了List集合而致使此問題的發生,如果用Set還出現此問題,則去看Set容器內的對象的類中是否是還有相似問題。

轉載:http://howsun.blog.sohu.com/119020926.html

相關文章
相關標籤/搜索