트러블슈팅
[Spring Data JPA] 무한참조 문제 - @JsonIgnoreProperties
pyogowoon
2023. 1. 10. 15:22
@PutMapping("/api/user/{id}")
public CMRespDto<?> update(
@PathVariable int id,
@Valid UserUpdateDto userUpdateDto,
BindingResult bindingResult, // 꼭@Valid가 적힌 다음파라메터에 적어야함
@AuthenticationPrincipal PrincipalDetails principalDetails) {
if (bindingResult.hasErrors()) {
Map<String, String> errorMap = new HashMap<>();
for (FieldError error : bindingResult.getFieldErrors()) {
errorMap.put(error.getField(), error.getDefaultMessage());
}
throw new CustomValidationApiException("유효성검사 실패", errorMap);
} else {
User userEntity = userService.회원수정(id, userUpdateDto.toEntity());
principalDetails.setUser(userEntity);
return new CMRespDto<>(1, "회원수정완료", userEntity);
//응답시에 userEntity의 모든 getter 함수가 호출되고 JSON으로 파싱하여 응답한다.
//이것 역시 또 List<Image>의 무한반복 문제.
}
}
맨 마지막줄 return new CMRespDto<>(1,"회원수정완료",userEntity); 에서
로직이 실행될 때 userEntity의 모든 getter 함수가 호출되고 JSON으로 파싱하여 응답되는데
이것 역시 List<image> 를 통해 User로 들어가는 무한반복 문제에 빠진다.
이런경우 image를 타고 들어가서 User를 읽을 때를 막아주면 해결되는데 이는
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(unique = true, length = 20)
private String username;
@Column(nullable = false)
private String password;
private String name;
private String website; //웹사이트
private String bio; // 자기소개
@Column(nullable = false)
private String email;
private String phone;
private String gender;
private String profileImageUrl;
private String role;
private LocalDateTime createDate;
@JsonIgnoreProperties("user")
@OneToMany(mappedBy ="user", fetch= FetchType.LAZY) //user는 Image의 변수를 넣어야함 //나는 연관관계의 주인이 아니다 를 알리는것.
//이걸 함으로써 DB가 컬럼을 만들지않으며 select 할때 user Id로 등록된 image들을 다 가져옴
// Lazy = User를 select할떄 해당 User id로 등록된 image들을 가져오지마 - 대신 getImages() 메소드가 호출될 때 가져와
// Eaguer = User를 select할때 해당 user Id로 등록된 image들을 전부 join해서 가져와!
private List<Image> images; // 양방향 매핑 / DB는 여러개못들어감 (리스트가 뭔지모름)
@PrePersist // DB에 INSERT 되기 직전에 실행
public void createDate(){
this.createDate = LocalDateTime.now();
}
}
User 도메인의 List<Image> images; 필드에
@JsonIgnoreProperties("변수이름") 을 지정해주면 해당 필드를 JSON파싱하지 않는다
즉 Images의 안에 user를 읽지않는다는 뜻