spring-data-jpa一對多、多對多雙向關聯,查詢操作的時候進入死迴圈問題
此處以多對多為例,解決查詢時進入死迴圈問題
1.使用者實體類
@Entity
@Table(name = "t_sys_user")
@Data
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
private String fullName;
private String email;
@ManyToMany(cascade = CascadeType.REMOVE)
@JoinTable(name = "t_sys_user_roles")
private List<Role> roles;
}
2.角色實體類
@Entity
@Table(name = "t_sys_role")
@Data
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@Lob
private String remark;
@ManyToMany(cascade = CascadeType.REMOVE, mappedBy = "roles")
private List<User> users; //被維護端
}
在使用插入資料的時候沒有任何問題,但是當查詢的時候報錯
java.lang.IllegalStateException: Cannot call sendError() after the response has been committed
at org.apache.catalina.connector.ResponseFacade.sendError(ResponseFacade.java:472) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
at javax.servlet.http.HttpServletResponseWrapper.sendError(HttpServletResponseWrapper.java:129) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
at javax.servlet.http.HttpServletResponseWrapper.sendError(HttpServletResponseWrapper.java:129) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
...
java.lang.StackOverflowError: null
at java.lang.ClassLoader.defineClass1(Native Method) ~[na:1.8.0_131]
at java.lang.ClassLoader.defineClass(ClassLoader.java:763) ~[na:1.8.0_131]
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) ~[na:1.8.0_131]
at java.net.URLClassLoader.defineClass(URLClassLoader.java:467) ~[na:1.8.0_131]
at java.net.URLClassLoader.access$100(URLClassLoader.java:73) ~[na:1.8.0_131]
at java.net.URLClassLoader$1.run(URLClassLoader.java:368) ~[na:1.8.0_131]
at java.net.URLClassLoader$1.run(URLClassLoader.java:362) ~[na:1.8.0_131]
at java.security.AccessController.doPrivileged(Native Method) ~[na:1.8.0_131]
at java.net.URLClassLoader.findClass(URLClassLoader.java:361) ~[na:1.8.0_131]
at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_131]
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335) ~[na:1.8.0_131]
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_131]
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:737) ~[jackson-databind-2.9.9.jar:2.9.9]
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) ~[jackson-databind-2.9.9.jar:2.9.9]
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:145) ~[jackson-databind-2.9.9.jar:2.9.9]
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:107) ~[jackson-databind-2.9.9.jar:2.9.9]
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:25) ~[jackson-databind-2.9.9.jar:2.9.9]
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727) ~[jackson-databind-2.9.9.jar:2.9.9]
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719) ~[jackson-databind-2.9.9.jar:2.9.9]
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) ~[jackson-databind-2.9.9.jar:2.9.9]
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:145) ~[jackson-databind-2.9.9.jar:2.9.9]
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:107) ~[jackson-databind-2.9.9.jar:2.9.9]
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:25) ~[jackson-databind-2.9.9.jar:2.9.9]
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727) ~[jackson-databind-2.9.9.jar:2.9.9]
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719) ~[jackson-databind-2.9.9.jar:2.9.9]
...
返回的資料
[{"id":1,"username":"admin","password":"$2a$10$.UblZbe8b/ESRiXrajVgo.HuhbJUezsPgpyD.tVrJraFmegiup.aS","fullName":"管理員","email":"admin@qq.com","roles":[{"id":1,"name":"管理員","remark":"系統管理員","users":[{"id":1,"username":"admin","password":"$2a$10$.UblZbe8b/ESRiXrajVgo.HuhbJUezsPgpyD.tVrJraFmegiup.aS","fullName":"管理員","email":"admin@qq.com","roles":[{"id":1,"name":"管理員","remark":"系統管理員","users":[{"id":1,"username":"admin","password":"$2a$10$.UblZbe8b/ESRiXrajVgo.HuhbJUezsPgpyD.tVrJraFmegiup.aS","fullName":"管理員","email":"admin@qq.com","roles":[{"id":1,"name":"管理員","remark":"系統管理員","users":[{"id":1,"username":"admin","password":"$2a$10$.UblZbe8b/ESRiXrajVgo.HuhbJUezsPgpyD.tVrJraFmegiup.aS","fullName":"管理員","email":"admin@qq.com","roles":[{"id":1,"name":"管理員","remark":"系統管理員","users":[{"id":1,"username":"admin","password":"$2a$10$.UblZbe8b/ESRiXrajVgo.HuhbJUezsPgpyD.tVrJraFmegiup.aS","fullName":"管理員","email":"admin@qq.com","roles":[{"id":1,"name":"管理員","remark":"系統管理員","users":[{"id":1,"username":"admin","password":"$2a$10$.UblZbe8b/ESRiXrajVgo.HuhbJUezsPgpyD.tVrJraFmegiup.aS","fullName":"管理員","email":"admin@qq.com","roles":[{"id":1,"name":"管理員","remark":"系統管理員","users":[{"id":1,"username":"admin","password":"$2a$10$.UblZbe8b/ESRiXrajVgo.HuhbJUezsPgpyD.tVrJraFmegiup.aS","fullName":"管理員","email":"admin@qq.com","roles":[{"id":1,"name":"管理員","remark":"系統管理員","users":[{"id":1,"username":"admin","password":"$2a$10$.UblZbe8b/ESRiXrajVgo.HuhbJUezsPgpyD.tVrJraFmegiup.aS","fullName":"管理員","email":"admin@qq.com","roles":[{"id":1,"name":"管理員","remark":"系統管理員","users":[{"id":1,"username":"admin","password":"$2a$10$.UblZbe8b/ESRiXrajVgo.HuhbJUezsPgpyD.tVrJraFmegiup.aS","fullName":"管理員","email":"admin@qq.com","roles":[{"id":1,"name":"管理員","remark":"系統管理員","users":[{"id":1,"username":"admin","password":"$2a$10$.UblZbe8b/ESRiXrajVgo.HuhbJUezsPgpyD.tVrJraFmegiup.aS","fullName":"管理員","email":"admin@qq.com","roles":[{"id":1,"name":"管理員","remark":"系統管理員","users":
...
首先這是雙向關聯,雙向關聯中你如果從資料庫裡面查詢一個User物件,那麼User物件裡面有Role,Role裡面又有User物件,那麼你用syso輸出User物件,如果toString方法裡面包含有輸出User.roles的話,那麼是必然會造成死迴圈的。如果你用sping mvc等框架將後臺資料返回給前臺也是同理,也會造成返回的JSON資料死迴圈
那麼要如何解決?
解決辦法就是在序列化例項的時候中斷迴圈就好。首先你要理解這不是spring-data-jpa的問題,這是一個序列化的問題。
例如如果是用jsckson對資料進行序列化的的話,可以使用下面的註解。
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@Entity
@Table(name = "t_sys_user")
@Data
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
private String fullName;
private String email;
@JsonIgnoreProperties("users")
@ManyToMany(cascade = CascadeType.REMOVE)
@JoinTable(name = "t_sys_user_roles")
private List<Role> roles;
}
序列化使用者類角色欄位裡的使用者集合欄位user.roles[i].users
時就忽略該欄位
Role類修改如下:
@JsonIgnoreProperties(value = { "roles" })
@ManyToMany(cascade = CascadeType.REMOVE, mappedBy = "roles")
private List<User> users; //被維護端
返回的結果無user.roles[i].users
欄位
[{"id":1,"username":"admin","password":"$2a$10$.UblZbe8b/ESRiXrajVgo.HuhbJUezsPgpyD.tVrJraFmegiup.aS","fullName":"管理員","email":"admin@qq.com","roles":[{"id":1,"name":"管理員","remark":"系統管理員","permissions":[]}],"enabled":true,"version":0,"enabledStr":"有效","authorities":null,"accountNonExpired":true,"accountNonLocked":true,"credentialsNonExpired":true}]
問題解決!
相關文章
- spring data jpa關聯查詢(一對一、一對多、多對多)Spring
- gorm 關係一對一,一對多,多對多查詢GoORM
- MyBatis表關聯 一對多 多對一 多對多MyBatis
- 多對多的操作問題
- JPA(3) 表關聯關係(多對一、一對多、多對多、一對一)
- hibernate(四) 雙向多對多對映關係
- Mybatis plus 一對多關聯查詢分頁不準確的問題MyBatis
- 由一個博問學到的SQL查詢方法 (一道多對多關係查詢的面試題)SQL面試題
- jpa一對多查詢
- 多對多關聯的時候,怎麼返回中間表的資料集合
- MyBatis 查詢資料時屬性中多對一的問題(多條資料對應一條資料)MyBatis
- 模型關聯一對多模型
- 多執行緒下HashMap的死迴圈問題執行緒HashMap
- 多執行緒 HashMap 死迴圈 問題解析執行緒HashMap
- Laravel多對多模型關聯Laravel模型
- 關於Hibernate一對多關聯儲存問題
- 03 註解:多對多查詢
- spring data jpa 多對一聯表查詢Spring
- MyBatis初級實戰之六:一對多關聯查詢MyBatis
- 關於Hibernate多層1對多關係查詢
- springDataJpa聯表查詢之多對多Spring
- Django Model各種操作 Meta 常用欄位 一對多操作 多對對操作 F Q查詢 聚合函式Django函式
- #MyBatis多表查詢 #多對一、一對多的兩種實現方式 @FDDLCMyBatis
- 使用者和角色多對多問題,物件間關聯處理問題物件
- 多對多關係自行維護單項關聯數量,加快分頁查詢
- sql一關聯多查詢時否定篩選出現的問題的解決SQL
- Mybatis09_一對一、一對多、多對多、延遲載入MyBatis
- Spring Data JPA 之 一對一,一對多,多對多 關係對映Spring
- Spring Boot 入門系列(二十八) JPA 的實體對映關係,一對一,一對多,多對多關係對映!Spring Boot
- mybatis入門基礎(六)----高階對映(一對一,一對多,多對多)MyBatis
- 多對一(主鍵)關係,create問題
- Mybatis【一對多、多對一、多對多】知識要點MyBatis
- Laravel 多對多關聯模型 CURD 詳解Laravel模型
- mybatis的一對多,多對一,以及多對對的配置和使用MyBatis
- JPA中對映關係詳細說明(一對多,多對一,一對一、多對多)、@JoinColumn、mappedBy說明APP
- Spring data jpa 多表查詢(三:多對多關係動態條件查詢)Spring
- Oracle多列統計資訊與直方圖對有關聯多列查詢影響Oracle直方圖
- 多對多關聯 attach() 相同的資料包錯