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":"[email protected]","roles":[{"id":1,"name":"管理员","remark":"系统管理员","users":[{"id":1,"username":"admin","password":"$2a$10$.UblZbe8b/ESRiXrajVgo.HuhbJUezsPgpyD.tVrJraFmegiup.aS","fullName":"管理员","email":"[email protected]","roles":[{"id":1,"name":"管理员","remark":"系统管理员","users":[{"id":1,"username":"admin","password":"$2a$10$.UblZbe8b/ESRiXrajVgo.HuhbJUezsPgpyD.tVrJraFmegiup.aS","fullName":"管理员","email":"[email protected]","roles":[{"id":1,"name":"管理员","remark":"系统管理员","users":[{"id":1,"username":"admin","password":"$2a$10$.UblZbe8b/ESRiXrajVgo.HuhbJUezsPgpyD.tVrJraFmegiup.aS","fullName":"管理员","email":"[email protected]","roles":[{"id":1,"name":"管理员","remark":"系统管理员","users":[{"id":1,"username":"admin","password":"$2a$10$.UblZbe8b/ESRiXrajVgo.HuhbJUezsPgpyD.tVrJraFmegiup.aS","fullName":"管理员","email":"[email protected]","roles":[{"id":1,"name":"管理员","remark":"系统管理员","users":[{"id":1,"username":"admin","password":"$2a$10$.UblZbe8b/ESRiXrajVgo.HuhbJUezsPgpyD.tVrJraFmegiup.aS","fullName":"管理员","email":"[email protected]","roles":[{"id":1,"name":"管理员","remark":"系统管理员","users":[{"id":1,"username":"admin","password":"$2a$10$.UblZbe8b/ESRiXrajVgo.HuhbJUezsPgpyD.tVrJraFmegiup.aS","fullName":"管理员","email":"[email protected]","roles":[{"id":1,"name":"管理员","remark":"系统管理员","users":[{"id":1,"username":"admin","password":"$2a$10$.UblZbe8b/ESRiXrajVgo.HuhbJUezsPgpyD.tVrJraFmegiup.aS","fullName":"管理员","email":"[email protected]","roles":[{"id":1,"name":"管理员","remark":"系统管理员","users":[{"id":1,"username":"admin","password":"$2a$10$.UblZbe8b/ESRiXrajVgo.HuhbJUezsPgpyD.tVrJraFmegiup.aS","fullName":"管理员","email":"[email protected]","roles":[{"id":1,"name":"管理员","remark":"系统管理员","users":[{"id":1,"username":"admin","password":"$2a$10$.UblZbe8b/ESRiXrajVgo.HuhbJUezsPgpyD.tVrJraFmegiup.aS","fullName":"管理员","email":"[email protected]","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":"[email protected]","roles":[{"id":1,"name":"管理员","remark":"系统管理员","permissions":[]}],"enabled":true,"version":0,"enabledStr":"有效","authorities":null,"accountNonExpired":true,"accountNonLocked":true,"credentialsNonExpired":true}]
问题解决!