微服务间调用导致的Could not write content: Infinite recursion (StackOverflowError)问题
2017-11-01 17:47
946 查看
最近在开发中遇到了一个奇葩的问题,在本地调用没有任何问题,只要是通过feign调用就出现递归调用,异常信息如下:
2017-11-01 17:23:10.302 ERROR 4172 --- [nio-6006-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: Infinite recursion (StackOverflowError) (through reference chain: org.hibernate.collection.internal.PersistentSet[0]->com.chhliu.srd.rdcloud.user.entity.SysPermission["roleList"]->org.hibernate.collection.internal.PersistentSet[0]->com.chhliu.srd.rdcloud.user.entity.SysRole["permissionList"]->org.hibernate.collection.internal.PersistentSet[0]->com.chhliu.srd.rdcloud.user.entity.SysPermission["roleList"]->org.hibernate.collection.internal.PersistentSet[0] with root cause
java.lang.StackOverflowError: null
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:709)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:149)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:112)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:25)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:704)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:690)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155)
从上面的异常信息可以看出,权限表和角色表出现了递归调用,并且最终导致了StackOverflowError的错误。从异常中可以看出,是由于feign在序列化的时候,使用的是jackson,jackson在序列化的时候,导致了递归调用。
角色表如下:
权限表如下:
@Entity
@Table(name = "t_sys_permission")
@Setter
@Getter
@NoArgsConstructor
@ToString(exclude = "roleList")
public class SysPermission implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@Id
@GeneratedValue
@Column(name = "permission_id")
private long permissionId;
/**
* 权限编码名称
*/
@Column(name = "permission_code")
private String permissionCode;
/**
* 名称
*/
@Column(name = "permission_name")
private String permissionName;
/**
* 一级菜单
*/
@Column(name = "first_menu")
private String firstMenu;
/**
* 二级菜单
*/
@Column(name = "second_menu")
private String secondMenu;
/**
* 资源路径
*/
@Column(name = "url")
private String url;
/**
* 权限字符串,menu例子:role:*,button例子:role:create,role:update,role:delete,role:view
*/
@Column(name = "permission")
private String permission;
/**
* 是否可用,如果不可用将不会添加给用户
*/
@Column(name = "available")
private Boolean available = Boolean.FALSE;
/**
* 权限- 角色关系定义 一个权限对应多个角色
*/
@JsonBackReference // 解决循环调用的问题
@ManyToMany@JoinTable(name = "t_sys_role_permission", joinColumns = {@JoinColumn(name = "permissionId") }, inverseJoinColumns = { @JoinColumn(name = "roleId") })private Set<SysRole> roleList;}
解决方案如下:
比如角色和权限是ManyToMany的关系,那么就在权限对应的角色的setter上加上@JsonBackReference注解,来解决问题,例如上例中在roleList属性上加了该注解。
2017-11-01 17:23:10.302 ERROR 4172 --- [nio-6006-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: Infinite recursion (StackOverflowError) (through reference chain: org.hibernate.collection.internal.PersistentSet[0]->com.chhliu.srd.rdcloud.user.entity.SysPermission["roleList"]->org.hibernate.collection.internal.PersistentSet[0]->com.chhliu.srd.rdcloud.user.entity.SysRole["permissionList"]->org.hibernate.collection.internal.PersistentSet[0]->com.chhliu.srd.rdcloud.user.entity.SysPermission["roleList"]->org.hibernate.collection.internal.PersistentSet[0] with root cause
java.lang.StackOverflowError: null
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:709)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:149)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:112)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:25)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:704)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:690)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155)
从上面的异常信息可以看出,权限表和角色表出现了递归调用,并且最终导致了StackOverflowError的错误。从异常中可以看出,是由于feign在序列化的时候,使用的是jackson,jackson在序列化的时候,导致了递归调用。
角色表如下:
@Entity @Table(name = "t_sys_role") @Setter @Getter @NoArgsConstructor @ToString(exclude = {"permissionList", "userList"}) public class SysRole implements Serializable { /** * */ private static final long serialVersionUID = 1L; /** * 角色编号 */ @Id @GeneratedValue @Column(name = "role_id") private Long roleId; /** * 角色标识 程序中判断使用,如"admin",这个是唯一的: */ @Column(name = "role_name") private String roleName; /** * 角色描述,UI界面显示使用 */ @Column(name = "description") private String description; /** * 是否可用,如果不可用将不会添加给用户 */ @Column(name = "available") private Boolean available = Boolean.FALSE; /** * 角色 -权限关系: 多对多关系; */ @ManyToMany(fetch = FetchType.EAGER) @JoinTable(name = "t_sys_role_permission", joinColumns = { @JoinColumn(name = "roleId") }, inverseJoinColumns = { @JoinColumn(name = "permissionId") }) private Set<SysPermission> permissionList; /** * 用户 - 角色关系定义; */ @JsonBackReference // 解决循环调用的问题 @ManyToMany @JoinTable(name = "t_sys_user_role", joinColumns = { @JoinColumn(name = "roleId")}, inverseJoinColumns = { @JoinColumn(name = "uid") }) private Set<Employee> userList; }
权限表如下:
@Entity
@Table(name = "t_sys_permission")
@Setter
@Getter
@NoArgsConstructor
@ToString(exclude = "roleList")
public class SysPermission implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@Id
@GeneratedValue
@Column(name = "permission_id")
private long permissionId;
/**
* 权限编码名称
*/
@Column(name = "permission_code")
private String permissionCode;
/**
* 名称
*/
@Column(name = "permission_name")
private String permissionName;
/**
* 一级菜单
*/
@Column(name = "first_menu")
private String firstMenu;
/**
* 二级菜单
*/
@Column(name = "second_menu")
private String secondMenu;
/**
* 资源路径
*/
@Column(name = "url")
private String url;
/**
* 权限字符串,menu例子:role:*,button例子:role:create,role:update,role:delete,role:view
*/
@Column(name = "permission")
private String permission;
/**
* 是否可用,如果不可用将不会添加给用户
*/
@Column(name = "available")
private Boolean available = Boolean.FALSE;
/**
* 权限- 角色关系定义 一个权限对应多个角色
*/
@JsonBackReference // 解决循环调用的问题
@ManyToMany@JoinTable(name = "t_sys_role_permission", joinColumns = {@JoinColumn(name = "permissionId") }, inverseJoinColumns = { @JoinColumn(name = "roleId") })private Set<SysRole> roleList;}
解决方案如下:
比如角色和权限是ManyToMany的关系,那么就在权限对应的角色的setter上加上@JsonBackReference注解,来解决问题,例如上例中在roleList属性上加了该注解。
相关文章推荐
- Could not write content: Infinite recursion (StackOverflowError)
- Could not write JSON: Infinite recursion (StackOverflowError) (through reference chain:
- Could not write JSON: Infinite recursion (StackOverflowError) (through reference chain:
- 解决Could not write JSON: Infinite recursion (StackOverflowError) (through reference chain
- json infinite recursion stackoverflowerror
- json infinite recursion stackoverflowerror错误解决方案
- HTTP Status 500 - Infinite recursion (StackOverflowError) (through reference chain: com.tianxi.entit
- json infinite recursion stackoverflowerror
- spring cloud eureka服务调用出现feign.codec.EncodeException: Could not write request: no suitable HttpMessa
- 在访问RESTful接口时出现:Could not write content: No serializer found for class的问题解决小技巧收集
- VS 2008 Setup Project Build 出现 ERROR: Could not create the file,发现是Chrome 启服务Software Protection的导致。
- Java 两个方法彼此调用导致java.lang.StackOverflowError
- 关于JNI配置Error: Could not find class file for 'XXX'问题(MAC Andriod Studio)
- 安装完MySQL 5.1,在最后配置启动服务时,出现could not start the service MySQL.Error:0 错误
- php 环境配置Could not execute menu item (internal error) [Exception] Could not perform service action 服务尚未启动
- Android布局嵌套太深导致的错误:StackOverflowError
- 如何解决Device Emulator 报 Error:Could not read save-state file的问题
- 问题3-Error occurred during initialization of VM Could not reserve enough space for object heap
- Compiler Error Message: CS0016: Could not write to output file 'c:\Windows\Microsoft.NET\Framework64
- 【python问题系列--4】ValueError: operands could not be broadcast together with shapes (100,3) (3,1)