JPA many-to-many relationship causing infinite recursion and stack overflow error

北城以北 提交于 2020-01-13 04:47:09

问题


I'm working on an EclipseLink project in which one user can "follow" another as can be done on social media sites. I have this set up with a User entity (referencing a table called users) which has a list of "followers" (users who follow that user) and another list of "following" (users that user is following). The relationship is defined in a separate table called followers which contains columns for the followed user's ID (user_id) and the following user's ID (follower_id).

My users model looks like this:

@Entity
@Table(name = "users")
@NamedQuery(name = "User.findAll", query = "SELECT u FROM USER u")
public class User {
    // other attributes
    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "follower", joinColumns = @JoinColumn(
        name = "user_id", referencedColumnName = "id"),
    inverseJoinColumns = @JoinColumn(
        name = "follower_id", referencedColumnName = "id"))
    private List<User> followers;

    @ManyToMany(mappedBy = "followers")
    private List<User> following;

    // other getters and setters
    public List<User> getFollowers() {
        return this.followers;
    }

    public List<User> getFollowing() {
        return this.following;
    }
}

The getFollowers() method seems to work fine, but when getFollowing() is called I get a bunch of console spam that culminates in a StackOverflowException:

com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion 
(StackOverflowError) (through reference chain: 
org.eclipse.persistence.indirection.IndirectList[0]-
>org.myproject.model.User["followers"]-
>org.eclipse.persistence.indirection.IndirectList[0]-
>org.myproject.model.User["following"]-
...
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase
.serializeFields(BeanSerializerBase.java:518)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize
(BeanSerializer.java:117)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer
.serializeContents(IndexedListSerializer.java:94)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer
.serializeContents(IndexedListSerializer.java:21)
...

Please let me know if I should provide more of the stack trace. Any hints?


回答1:


Every time you have @OneToMany (a collection) you need to add @JsonIgnore to it or else it will cause an infinite loop which results in a stack overflow exception because it keeps looking up between the parent(the one side) and the child (the many side) For more info on dealing with this kind of problems check this excellent article http://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion




回答2:


I tried everything what I found in the web and it didn't work. None of any annotation. But I found a solution after a huge fight with this issue.

First point you need to add to both entities (not the relational one) this annotation:

@JsonIgnoreProperties({"hibernateLazyInitializer", "handler", "relationClass"})
public class YourClass { ...
}

Where "relationClass" is the name of the List/Set of your class for the relations:

For example:

  @OneToMany(mappedBy = "yourClass", cascade = CascadeType.ALL, fetch = FetchType.LAZY,  orphanRemoval = true)
    private Set<RelationClass> relationClass;

You also need to specify "hibernateLazyInitializer", "handler" in the annotation or it will cause serialization problem.

After it if you see the table that define relation table and you will see rows in there, and in your JSON response will not be any loop anymore. So as I think the best solution is also create a repository for the relation tablee and access the data from there.

Hope it will help someone!



来源:https://stackoverflow.com/questions/43481353/jpa-many-to-many-relationship-causing-infinite-recursion-and-stack-overflow-erro

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!