亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

spring-data-jpa多對多雙向關聯,查詢的時候進入死循環

spring-data-jpa多對多雙向關聯,查詢的時候進入死循環

qq__4787 2017-10-20 00:11:48
兩個實體類User@Data @Entity @Table(name?=?"sys_user") public?class?User?{ ????@Id ????@GeneratedValue ????@Column(name?=?"user_id") ????private?Integer?userId; ????@Column(name?=?"username") ????private?String?username; ????@ManyToMany(cascade?=?{CascadeType.ALL},?fetch?=?FetchType.LAZY) ????@JoinTable( ????????????name?=?"user_role", ????????????joinColumns?=?{@JoinColumn(name?=?"user_id")}, ????????????inverseJoinColumns?=?{@JoinColumn(name?=?"role_id")} ????) ????private?Set<Role>?roles; }Role@Data @Entity @Table(name?=?"sys_role") public?class?Role?{ ????@Id ????@Column(name?=?"role_id") ????private?Integer?roleId; ????@Column(name?=?"role_name",?unique?=?true) ????private?String?roleName; ????@ManyToMany(cascade?=?{CascadeType.ALL},?fetch?=?FetchType.LAZY,?mappedBy?=?"roles") ????private?Set<User>?users;測試代碼@Transactional ????@Test ????public?void?save()?throws?Exception{ ????????Set<Role>roles?=?new?HashSet<Role>(); ????????roles.add(new?Role(1,?"USER")); ????????roles.add(new?Role(2,?"ADMIN")); ????????repository.save(new?User("張三",?roles)); ????} ????@Transactional ????@Test ????public?void?findAll(){ ????????List<User>?users?=?repository.findAll(); ????????for?(User?user?:?users)?{ ????????????System.out.println(user); ????????} ????}在使用插入數據的時候沒有任何問題,但是當查詢的時候報錯org.hibernate.LazyInitializationException:?failed?to?lazily?initialize?a?collection?of?role:?wang.xiaoqiang.manytomany.entity.User.roles,?could?not?initialize?proxy?-?no?Session這個可以理解,懶加載的時候丟失了session無法獲取roles信息,當將user中的集合設置為急加載模式,結果就遇到StackOverflowError哪位大佬有相關經歷,幫幫忙。。。
查看完整描述

1 回答

已采納
?
特南克斯

TA貢獻14條經驗 獲得超9個贊

首先你要理解這是雙向關聯,雙向關聯中你如果從數據庫里面查詢一個User對象,那么User對象里面有Role,Role里面又有User對象,那么你用syso輸出User對象,如果toString方法里面包含有輸出User.roles的話,那么是必然會造成死循環的。如果你用sping mvc等框架將后臺數據返回給前臺也是同理,也會造成返回的JSON數據死循環

那么要如何解決?

解決辦法就是在序列化實例的時候中斷循環就好。首先你要理解這不是spring-data-jpa的問題,這是一個序列化的問題。

例如如果是用jsckson對數據進行序列化的的話,可以使用下面的注解。

import?com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@Data
@Entity
@Table(name?=?"sys_user")
public?class?User?{
????@Id
????@GeneratedValue
????@Column(name?=?"user_id")
????private?Integer?userId;
????@Column(name?=?"username")
????private?String?username;
????@JsonIgnoreProperties(value?=?{?"users"?})
????@ManyToMany(cascade?=?{CascadeType.ALL},?fetch?=?FetchType.LAZY)
????@JoinTable(
????????????name?=?"user_role",
????????????joinColumns?=?{@JoinColumn(name?=?"user_id")},
????????????inverseJoinColumns?=?{@JoinColumn(name?=?"role_id")}
????)
????private?Set<Role>?roles;
}

這樣的話,你再序列化User對象時,

user.roles 這個對象中只有 user.roles[i].id 和? users.roles[i].name 而沒有 user.roles.users?。。?!

ok,問題解決?。。?/p>


查看完整回答
3 反對 回復 2017-11-01
  • qq__4787
    qq__4787
    非常感謝!原來一直是因為toString()方法中循環調用引發的問題,之前我也嘗試著將重寫toString()方法,避免循環調用。結果發現并沒有效果,原來是使用lombok中的@Data注解后會覆蓋掉原來的toString()方法,導致自定義的toString()方法并未生效。看來以后測試中也的看情況的使用toString()方法了。。。
  • 特南克斯
    特南克斯
    這個問題也困擾了我一段時間,但是到現在我也沒有完美的解決方法。 我見過一些API后臺是關聯深度是可以控制的,類似relation_depth = 0 返回數據不包含子對象,也就是沒有user.roles。relation_depth = 1 返回數據有user.roles。但是沒有user.roles.users。還可以更深。因為復雜的數據庫表結構可能不僅僅是一層的多對多。 但是絕大多數的情況下關聯深度為1,一般都可以用了。 至于toString,你只要注意下,不要對象循環輸出,就不是內存溢出了,也是可以用的
  • qq_白天不懂爺的黑_2
    qq_白天不懂爺的黑_2
    請問onetoone怎么解決死循環的問題呢?
點擊展開后面3
  • 1 回答
  • 0 關注
  • 10208 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號