1. 개요
문득 DB의 Member 테이블을 보던 중 너무 많은 Null 값이 존재하는 게 신경 쓰였다.
회원의 Role은 기업, 노동자로 나눠져있고 각 Role마다 갖는 필드가 다르기 때문에 @Embeddable로 관리하고 있었다.
그렇다 보니 기업은 노동자가 갖는 컬럼은 전부 null이고, 노동자는 기업이 갖는 컬럼은 전부 null이었다.
프로젝트에선 Spring Data JPA의 기본 구현체인 Hibernate를 사용하고 있는데, Hibernate 구현체에선 @Embedded 객체의 모든 필드의 값이 null이면 해당 객체 자체를 null로 설정하게 된다.
따라서 해당 클래스를 사용하려고 할때 NullPointerException이 발생해버린다.
이를 해결하기 위해선 2가지 방법으로 해결할 수 있다.
해결 - 1. Null일 수 없는 값을 값 사용
예를 들어 생성되는 날짜가 Embeddable 내에 반드시 포함되게 하여 최소한 값 하나는 null이 되지 않도록 하는 방법을 이용해서 하는 방법이 있을 수 있고
@Column(updatable = false)
@CreatedDate
private LocalDateTime createdDate;
더미 데이터를 Embeddable 내에 포함되게 하여 null이 되지 않도록 하는 방법이 있다.
@Formula("25")
private int age;
해결 - 2. yml 설정
이 문제는 이미 많은 사람들이 겪었고 이에 대한 논의가 활발하게 이루어졌다. 결국 Hibernate에서 해당 설정을 변경할 수 있게 2016년 5.1 패치로 수정하게 되었다.
나는 간단하게 yml 설정으로 NullPointerException이 터지는걸 막아줬다.
spring:
jpa:
properties:
hibernate:
create_empty_composites:
enabled: true
기업 계정으로 로그인 후 요청을 보내고, 값이 전부 null인 workerInfo embedded 객체에 접근했을 때 예외가 터지는 지 간단하게 테스트해봤다.
@GetMapping("/null-test")
public String test(@AuthenticationPrincipal PrincipalDetails principalDetails) {
Member member = memberRepository.findById(principalDetails.getMember().getId()).get();
System.out.println(member.getWorkerInfo().getWorkerName());
return "test";
}
yml 설정 전
yml 설정 후
embedded 객체의 필드들이 전부 null이더라도 embedded 객체 자체는 null로 저장되지 않는 걸 확인할 수 있다.
'Spring Boot, JAVA 🌱' 카테고리의 다른 글
@Transactional과 synchronized를 같이 사용하면 왜 안 될까? (0) | 2024.05.31 |
---|---|
동시성 문제를 해결하는 다양한 방법, 분산 환경에서의 동시성 문제 (0) | 2024.05.30 |
하나의 요청에 나가는 쿼리 개수를 효율적으로 세어보자 (Hibernate StatementInspector, Spring AOP) (1) | 2024.05.21 |
AWS Lambda를 이용한 Image Resize 도입 (썸네일 이미지 성능 개선) (1) | 2024.05.07 |
지도의 경계 정보를 가져와 근처 일자리 공고 조회 기능 개발 (0) | 2024.05.06 |