sm 기술 블로그

[스프링 부트] 양방향 관계 엔티티 사이클 방지(JsonIdentityInfo) 본문

스프링부트

[스프링 부트] 양방향 관계 엔티티 사이클 방지(JsonIdentityInfo)

sm_hope 2022. 7. 13. 12:36

DB

DROP DATABASE
IF EXISTS sbb;

CREATE DATABASE sbb;

CREATE TABLE Question (
    id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
    `subject` VARCHAR(200) NOT NULL,
    content TEXT NOT NULL,
    create_date DATETIME NOT NULL,
    answer_id INT(11) UNSIGNED
);

INSERT INTO Question SET
create_date = NOW(),
`subject` = '질문 1',
content = '질문내용 1',
answer_id = 1;

INSERT INTO Question SET
create_date = NOW(),
`subject` = '질문 2',
content = '질문내용 2',
answer_id = 2;

INSERT INTO Question SET
create_date = NOW(),
`subject` = '질문 3',
content = '질문내용 3',
answer_id = 3;

CREATE TABLE Answer (
    id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
    content TEXT NOT NULL,
    create_date DATETIME NOT NULL,
    question_id INT(11) UNSIGNED NOT NULL
);

INSERT INTO Answer SET
create_date = NOW(),
content = '답변내용 1',
question_id = 1;

INSERT INTO Answer SET
create_date = NOW(),
content = '답변내용 2',
question_id = 2;

INSERT INTO Answer SET
create_date = NOW(),
content = '답변내용 3',
question_id = 3;

SELECT * FROM Question;
SELECT * FROM Answer;

Question

package com.mysite.sbb.domain;

import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import lombok.Getter;
import lombok.Setter;

import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.List;

@Getter
@Setter
@Entity
@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class)
public class Question {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column(length = 200)
    private String subject;

    @Column(columnDefinition = "TEXT")
    private String content;

    private LocalDateTime createDate;

    @OneToMany(mappedBy = "question", cascade = CascadeType.REMOVE)
    private List<Answer> answerList;
}

Answer

package com.mysite.sbb.domain;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import javax.persistence.*;
import java.time.LocalDateTime;

@Getter
@Setter
@Entity
@ToString
public class Answer {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column(columnDefinition = "TEXT")
    private String content;

    private LocalDateTime createDate;

    @ManyToOne
    private Question question;
}

설명

다음과 같이 질문을 하고 답변을 받는 방식을 만들고자 한다.
이때 질문과 답변을 연결해서 페이지에 출력하게 되는데, 여러가지 문제가 발생한다.

1번) 답변에서 질문을 어떻게 같이 표출하냐?

자 보면 DB에 question_id를 썼다.
그런데 엔티티 자체에는 question_id가 없고, question 이라는 놈이 있다.
question_id가 들어가는 자리에 question 엔티티를 @ManyToOne을 이용해서 집어 넣어준다고 생각하면 된다.
ManyToOne은 하나에 많은 것들을 넣는다! 라고 생각하면 된다.

그림으로 설명하면,

2번) @JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class) 이건 뭐에여?

자 보면 @ManyToOne 과 @OneToMany가 있다.
그러면


다음과 같이 순환을 돌기 때문에 무한으로 출력이 된다.

이것을 방지하기 위해서 @JsonIdentityInfo 어노테이션을 쓰는 것이다.

@JsonIdentityInfo의 의의를 보면 : 양방향 관계 엔티티 사이클 방지 이다.
자세한 내용을 여기를 참고하자.

'스프링부트' 카테고리의 다른 글

[스프링 부트] CascadeType.REMOVE  (0) 2022.07.14
[스프링 부트] 폰트적용  (0) 2022.07.13
[스프링부트] JSP와 Thymeleaf  (0) 2022.07.11
[스프링 부트] 타임리프 URL  (0) 2022.07.10
[스프링부트] CRUD  (0) 2022.07.09
Comments