[기초 API 구현 2] - 댓글 작성 버튼

박성규·2022년 6월 1일
0

[스프링 부트]

목록 보기
30/38
post-thumbnail

1.Controller

 @PostMapping("/notice/detail/comment")
    public String commentWrite(@RequestBody CommentRequestDto commentRequestDto){
        noticeService.commentWrite(commentRequestDto);
        return "1";
    }

2.Service

 public void commentWrite(CommentRequestDto commentRequestDto) {
        Optional<Notice> notice = noticeRepository.findById(commentRequestDto.getId());
        Comment comment = new Comment();
        comment.setNotice(notice.get());
        comment.setComment(commentRequestDto.getComment());
        comment.setUsername(commentRequestDto.getUsername());
        comment.setDate(commentRequestDto.getDate());
        commentRepository.save(comment);
    }

3.Entity 구조

package com.spring.loginprac.model;

import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.spring.loginprac.dto.NoticeDto;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Setter
@Getter // get 함수를 일괄적으로 만들어줍니다.
@NoArgsConstructor // 기본 생성자를 만들어줍니다.
@Entity // DB 테이블 역할을 합니다.
public class Notice {
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Id
    private Long id;

    // nullable: null 허용 여부
    // unique: 중복 허용 여부 (false 일때 중복 허용)
    @Column(nullable = false)
    private String username;

    @Column(nullable = false)
    private String title;

    @Column(nullable = false)
    private String description;

    @OneToMany(mappedBy = "notice", cascade = CascadeType.REMOVE)
    @JsonBackReference
    private List<Comment> comments = new ArrayList<>();

    public Notice(NoticeDto noticeDto) {
        this.username = noticeDto.getUsername();
        this.title = noticeDto.getTitle();
        this.description = noticeDto.getDescription();

    }
}
package com.spring.loginprac.model;


import com.fasterxml.jackson.annotation.JsonManagedReference;
import com.spring.loginprac.dto.NoticeDto;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import javax.persistence.*;
import java.util.Date;

@Getter
@Setter
@NoArgsConstructor
@Entity
public class Comment {
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Id
    private Long id;

    // nullable: null 허용 여부
    // unique: 중복 허용 여부 (false 일때 중복 허용)
    @Column(nullable = false)
    private String username;

    @Column(nullable = false)
    private String comment;

    @Column(nullable = false)
    private Date date;

    @ManyToOne
    @JsonManagedReference
    @JoinColumn(name = "post_id")
    private Notice notice;
}

트러블 슈팅

Notice와 Comment는 일대다, 다대일 관계를 가진다.

그렇기에 @ManyToOne, @OneToMany 어노테이션을 활용해 관계를 지어 주었다.

하지만 여기서 문제가 발생했다.
실행 후 댓글을 달 때
IllegalStateException이 발생한것.

오류 코드를 보니 에러가 상당히 길다... 뭔가 재귀 형식이 발생한건가?

내가 이렇게 요청을 많이 보내진 않았는데 문제를 확인해 보니

comment 작성 - notice 발동 - comment 발동- notice 발동.... 이런식으로 무한 반복이 되다가 stackoverflow가 발생했다.

해결 방안으로는 @JsonManagedReference와 @JsonBackReference를 각각 달아주어 무한 반복을 방지했다.

결과는 성공~!

0개의 댓글

관련 채용 정보