Home » Java » java – Could not write JSON: Infinite recursion (StackOverflowError)-Exceptionshub

java – Could not write JSON: Infinite recursion (StackOverflowError)-Exceptionshub

Posted by: admin February 23, 2020 Leave a comment

Questions:

This is the first entity:

@Entity

@Table(name = "matches")

@Data

@Builder(toBuilder = true)

@AllArgsConstructor

@NoArgsConstructor

public class Match {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long matchId;
    private int playersMaxCount;
    private long tournamentId;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "gameId", nullable = false)
    private Game game;

    @OneToMany(mappedBy = "match")
    private Set<PlayersInMatch> players;

    private String matchStatus = "Preparing"; //Started and Ended
    private String matchResult = "none";
    private String matchLocation;
    private String matchType;
    private int scoreToWin;
}

And this is the next:

@Entity
@Data
@Table(name = "InMatchPlayers")
public class PlayersInMatch {

    @EmbeddedId
    MatchesPlayersComposKey inMatchPlayerId;

    @ManyToOne(fetch = FetchType.EAGER)
    @MapsId("matchId")
    @JoinColumn(name = "matchId")
    private Match match;

    @ManyToOne(fetch = FetchType.EAGER)
    @MapsId("playerAuth")
    @JoinColumn(name = "playerAuth")
    private Player player;

    private String result;

    private int score;
}

Controller method:

@GetMapping("/matches/{matchId}")
    public Optional<Match> getMatch(@PathVariable("matchId") long matchId){
        return matchService.getMatch(matchId);
    }

Service method:

    @Transactional
    public Optional<Match> getMatch(long matchId){
        return matchRepository.findById(matchId);
    }

When i try to get Match with players set the size of which is greater than 0, I see the following error: Could not write JSON: Infinite recursion (StackOverflowError); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: com.griddynamics.eSports.model.Match["players"])
I’m new to java, so I would really appreciate your help! 🙂

UPD:

@Entity
@Table(name = "matches")
@Data
@Builder(toBuilder = true)
@AllArgsConstructor
@NoArgsConstructor
public class Match {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long matchId;
    private int playersMaxCount;
    private long tournamentId;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "gameId", nullable = false)
    private Game game;

    @JsonIgnore
    @OneToMany(mappedBy = "match")
    private Set<PlayersInMatch> players;

    private String matchStatus = "Preparing"; //Started and Ended
    private String matchResult = "none";
    private String matchLocation;
    private String matchType;
    private int scoreToWin;
}
How to&Answers:

There are probably a number of similar questions that will be linked here that would answer this, but the gist is simple:

Your Match has Players. Players have a Match. When it tries to serialize those, there is a circular reference (Match -> Player -> Match -> Player -> Overflow). You’d need to update your serialize to ignore that circular reference, and not attempt to print the Match object on the Player.

It appears you’re using Jackson JSON, the docs on the ignore attribute are here.