ManyToMany 关系导致 *** 错误
Posted
技术标签:
【中文标题】ManyToMany 关系导致 *** 错误【英文标题】:ManyToMany relationship leads to *** error 【发布时间】:2019-09-14 05:31:30 【问题描述】:我有一个名为 User 的实体,它有一组角色。我还有一个 Role 实体,它有一组用户。(这只是一个用于学习目的的练习应用程序。)
public class User
private String firstName;
private String lastName;
@ManyToMany
@JoinTable(name="user_role",
joinColumns=@JoinColumn(name="user_id"),
inverseJoinColumns=@JoinColumn(name="role_id"))
private Set<Role> roles;
//getters setters
public class Role
private String name;
@ManyToMany(mappedBy="roles")
private Set<Users> users;
//getters setters
Table: User (id, firstname, lastname....)
Table: Role (id, name)
Table: User_Role (id, user_id, role_id)
问题是 - 我有一个 UserController (REST API) 来发送用户列表 - 它导致 *** 错误。用户尝试加载角色,而角色又尝试加载用户等。
我的问题是 - 如何避免这种情况?我也看到很多类似的设计。例如:https://viralpatel.net/blogs/hibernate-many-to-many-annotation-mapping-tutorial/
他们怎么没有遇到过这样的问题?
java.lang.***Error: null
at java.lang.ClassLoader.defineClass1(Native Method) ~[na:1.8.0_191]
at java.lang.ClassLoader.defineClass(ClassLoader.java:763) ~[na:1.8.0_191]
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) ~[na:1.8.0_191]
at java.net.URLClassLoader.defineClass(URLClassLoader.java:468) ~[na:1.8.0_191]
at java.net.URLClassLoader.access$100(URLClassLoader.java:74) ~[na:1.8.0_191]
at java.net.URLClassLoader$1.run(URLClassLoader.java:369) ~[na:1.8.0_191]
at java.net.URLClassLoader$1.run(URLClassLoader.java:363) ~[na:1.8.0_191]
at java.security.AccessController.doPrivileged(Native Method) ~[na:1.8.0_191]
at java.net.URLClassLoader.findClass(URLClassLoader.java:362) ~[na:1.8.0_191]
at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_191]
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349) ~[na:1.8.0_191]
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_191]
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:737) ~[jackson-databind-2.9.8.jar:2.9.8]
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) ~[jackson-databind-2.9.8.jar:2.9.8]
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:145) ~[jackson-databind-2.9.8.jar:2.9.8]
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:107) ~[jackson-databind-2.9.8.jar:2.9.8]
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:25) ~[jackson-databind-2.9.8.jar:2.9.8]
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727) ~[jackson-databind-2.9.8.jar:2.9.8]
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719) ~[jackson-databind-2.9.8.jar:2.9.8]
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) ~[jackson-databind-2.9.8.jar:2.9.8]
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:145) ~[jackson-databind-2.9.8.jar:2.9.8]
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:107) ~[jackson-databind-2.9.8.jar:2.9.8]
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:25) ~[jackson-databind-2.9.8.jar:2.9.8]
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727) ~[jackson-databind-2.9.8.jar:2.9.8]
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719) ~[jackson-databind-2.9.8.jar:2.9.8]
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) ~[jackson-databind-2.9.8.jar:2.9.8]
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:145) ~[jackson-databind-2.9.8.jar:2.9.8]
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:107) ~[jackson-databind-2.9.8.jar:2.9.8]
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:25) ~[jackson-databind-2.9.8.jar:2.9.8]
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727) ~[jackson-databind-2.9.8.jar:2.9.8]
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719) ~[jackson-databind-2.9.8.jar:2.9.8]
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) ~[jackson-databind-2.9.8.jar:2.9.8]
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:145) ~[jackson-databind-2.9.8.jar:2.9.8]
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:107) ~[jackson-databind-2.9.8.jar:2.9.8]
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:25) ~[jackson-databind-2.9.8.jar:2.9.8]
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727) ~[jackson-databind-2.9.8.jar:2.9.8]
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719) ~[jackson-databind-2.9.8.jar:2.9.8]
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) ~[jackson-databind-2.9.8.jar:2.9.8]
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:145) ~[jackson-databind-2.9.8.jar:2.9.8]
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:107) ~[jackson-databind-2.9.8.jar:2.9.8]
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:25) ~[jackson-databind-2.9.8.jar:2.9.8]
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727) ~[jackson-databind-2.9.8.jar:2.9.8]
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719) ~[jackson-databind-2.9.8.jar:2.9.8]
【问题讨论】:
如果将用户返回为json,则需要添加json注释以忽略角色的用户字段...否则json库(gson?)会进入这个无限循环 你能告诉我们你的堆栈跟踪吗?可能是序列化时出错。 @antoine.lange 是的。它发生在我们序列化时 您可以查看***.com/questions/3325387/…了解更多详情 Infinite Recursion with Jackson JSON and Hibernate JPA issue的可能重复 【参考方案1】:我想在 json 序列化过程中有一个循环引用。
因此,您需要使用@JsonIgnore
注解从序列化过程中排除这两个字段之一。
在此处查看之前的回复:https://***.com/a/39985263/2311723
【讨论】:
【参考方案2】:或者您可以将您的实体转换为 DTO(数据传输对象)并返回 DTO。我建议不要直接返回实体
【讨论】:
以上是关于ManyToMany 关系导致 *** 错误的主要内容,如果未能解决你的问题,请参考以下文章
如何在Java-EE中使用hibernate实现ManyToMany关系?