JPA에서 양방향으로 연결된 엔티티를 json으로 직렬화할 때, 즉, Entity To Json serialize할 때 (보통 controller 단) 순한 참조가 발생할 수 있다.
이를 해결하기 위해 Jackson 라이브러리의 @JsonIgnore 어노테이션이나 @JsonManagedReference & @JsonBackReference 어노테이션을 사용하여 직렬화를 제한할 수 있다.
Jackson은 스프링에서 JSON을 다룰 때 사용하는 라이브러리다.
spring-boot-stater-web 의존성을 주입하면 Jackson 라이브러리가 자동으로 포함된다.
1. @JsonIgnore
필드 레벨에 적용되어 직렬화 시 포함시키고 싶지 않은 필드에 선언한다.
@Entity
public class Team {
@JsonIgnore
public Long id;
public String name;
}
/** @JsonIgnore 적용 전 */
{
"id" : 1,
"name" : "My Bean"
}
/** @JsonIgnore 적용 후 */
{
"name" : "My Bean"
}
@JsonIgnoreProperties 애노테이션을 사용할 경우 클래스 레벨에 적용되어 클래스 단위로도 지정이 가능하다.
2. @JsonManagedReference & @JsonBackReference
양방향 관계에서 직렬화 방향을 설정하여 순환 참조를 해결할 수 있도록 설계되었다.
@JsonManagedReference
- 연관관계 주인이 아닌 Entity에 선언한다.
- 직렬화에 포함된다.
@Entity
public class Team {
@Id @GeneratedValue
@Column(name = "TEAM_ID")
private Long id;
.....생략.....
@OneToMany(mappedBy = "team") // 양방향 연관관계
@JsonManagedReference
private List<Member> members = new ArrayList<>(); // 회원 컬렉션
@JsonBackReference
- 연관관계의 주인 Entity에 선언한다.
- 직렬화에서 제외된다.
@Entity
public class Member {
@Id @GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
.....생략.....
@ManyToOne // 양방향 연관관계 주인
@JoinColumn(name = "TEAM_ID")
@JsonBackReference // 추가
private Team team;
사실 Response의 반환 타입으로 Entity 객체 자체를 넘기는 행위는 권장되지 않으며, DTO 객체를 생성하여 필요한 데이터만 반환하는 것이 더 현명한 방법이다.
Reference
https://data-make.tistory.com/727
'Framework > JPA' 카테고리의 다른 글
[JPA] 페이징 처리 성능 최적화하기 (1) | 2024.02.11 |
---|---|
[QueryDSL] DTO로 조회하기 (0) | 2023.10.15 |
[JPA] 다대일 매핑에서 @JoinColumn의 역할 (0) | 2023.10.05 |
[JPA] @MappedSupperclass vs @Embedded & @Embeddable (0) | 2023.10.01 |