JAVA/Spring Boot

(디버깅)일대다 양방향 Response Error

ri5 2021. 7. 2. 17:54

Error log

java.lang.IllegalStateException: Cannot call sendError() after the response has been committed

 

Game

@Getter
@Entity
@Table(name = "GAMES")
@NoArgsConstructor
public class Game {

    // 게임 아이디(PK)
    @Id
    @Column(name = "GAME_ID")
    private Long gameId;
    // 게임 이름
    @Column(name = "GAME_NAME")
    private String gameName;
    // 게임 정보
    @Column(name = "GAME_INFO")
    private String gameInfo;
    
    ...

    @OneToMany(mappedBy = "game")
    private List<GameTag> gameTags = new ArrayList<>();

    @Builder
    public Game(Long gameId, String gameName, String gameInfo, Date launchDate, String evaluation, String imgUrl, String videoUrl, String devCompany, String distributor) {
        this.gameId = gameId;
        this.gameName = gameName;
        this.gameInfo = gameInfo;
        this.launchDate = launchDate;
        this.evaluation = evaluation;
        this.imgUrl = imgUrl;
        this.videoUrl = videoUrl;
        this.devCompany = devCompany;
        this.distributor = distributor;
    }
}

 

 

Response

@Getter
public class GamesListResponseDto {
    // 게임 아이디(PK)
    private Long gameId;
    // 게임 이름
    private String gameName;
    // 게임 정보
    private String gameInfo;
   
   ....

    private List<GameTag> gameTags = new ArrayList<>();

    public GamesListResponseDto(Game entity) {
        this.gameId = entity.getGameId();
        this.gameName = entity.getGameName();
        this.gameInfo = entity.getGameInfo();
        this.launchDate = entity.getLaunchDate();
        this.evaluation = entity.getEvaluation();
        this.imgUrl = entity.getImgUrl();
        this.videoUrl = entity.getVideoUrl();
        this.devCompany = entity.getDevCompany();
        this.distributor = entity.getDistributor();
        this.gameTags = entity.getGameTags();
    }
}

Service

@Transactional(readOnly = true)
public List<GamesListResponseDto> findAllDesc() {
  return gameRepository.findAllDesc().stream()
  .map(GamesListResponseDto::new)
  .collect(Collectors.toList());
}

 


DEBUG

Game 안에 있는 GameTag 리스트가 Game을 참조하고 GameTag안에 있는 Game이 서로를 참조하면서 무한 재귀함수가 실행 되게 된다.

Game Entity에게 @JsonIdentityInfo 또는 @JsonIgnore 설정을 해서 무한재귀를 끊어야 한다.