일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- 스프링 시큐리티
- 다이나믹 프록시
- 스프링
- test
- Junit5
- 모던 자바 인 액션
- 운영체제
- java
- OS
- Deadlock
- 객체지향
- MST
- BOJ
- 프록시
- 파이썬
- CS
- 알고리즘
- Spring
- redis
- 리플렉션
- spring security
- 백준
- Python
- 약수
- proxy
- 문자열
- Reflection
- 최소 신장 트리
- 모던자바
- 자바
- Today
- Total
Dev 달팽이 @_''
[JPA] Entity Default Value 삽입(DynamicInsert) 본문
서론
프로젝트를 하다보면 Entity에 Default Value 값을 지정하는 경우가 자주 있습니다. 이럴 경우 매번 Entity를 생성할 때 직접 Default 값을 넣어주었는데 이번 사이드 프로젝트에서는 다른 방법을 사용해 보았습니다.
환경 : Java 11, MySQL, Springboot
준비
간단하게 Entity는 Product만 준비했습니다. 이번 예제에서 Default Value를 사용하는 칼럼은 삭제 여부를 체크하는 isDeleted와 생성 시간을 담는 createdAt 입니다.
Product.class
package com.example.jpatest;
import java.time.LocalDateTime;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.DynamicInsert;
@Entity
@Getter
@DynamicInsert
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "product_id")
private Long id;
@Column(nullable = false, length = 45)
private String name;
@Column(nullable = false)
private Integer price;
@Column(nullable = false, length = 100)
private String description;
@Column(columnDefinition = "0")
private Boolean isDeleted;
@Column(columnDefinition = "CURRENT_TIMESTAMP")
private LocalDateTime createdAt;
}
ProductDto.class
package com.example.jpatest;
import lombok.Getter;
@Getter
public class ProductDto {
private String name;
private Integer price;
private String description;
public Product toEntity() {
return Product.builder().name(name).price(price).description(description).build();
}
}
ProductService.class
package com.example.jpatest;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class ProductService {
public final ProductRepository productRepository;
public void insertProduct(ProductDto productDto) {
Product product = productDto.toEntity();
productRepository.save(product);
}
}
테스트
ProductServiceTest.class
package com.example.jpatest;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class ProductServiceTest {
@Autowired
private ProductService productService;
@Test
void insertProduct() {
ProductDto productDto1 = new ProductDto("product1",3000,"product1 description");
productService.insertProduct(productDto1);
}
}
Hibernate 쿼리 확인
@DynamicInsert 를 썻을 경우
실제 값이 들어간 칼럼만 들어간 것을 확인 할 수 있다.
@DynamicInsert 를 안썻을 경우
당연히 결과는 에러가 나고 값이 들어가지 않은 컬럼에 insert를 넣지 않은 부분은 null이 들어가는 걸 알 수 있습니다.
마무리
처음에 Entity를 정의할 때, columnDefinition을 사용하면 알아서 정해놓은 Default Value가 들어간다고 생각했습니다. 하지만 이는 테이블을 생성할 때 제약조건을 걸어주는 것이었습니다.
DynamicInsert를 사용하기 전에는 Entity를 생성할 때 직접 Default Value를 넣어줬는데 이보다 DynamicInsert를 사용하는 것이 성능상으로도 더 좋습니다.
DynamicInsert 말고도 Update에 사용하는 DynamicUpdate도 존재합니다.
columnDefinition과 DynamicInsert를 혼동해서 사용하지 말자!
직접 Default Value를 넣어주는 것보다 DynamicInsert를 사용하는 것이 더 좋은 성능을 낸다!
참고 : https://mangchhe.github.io/jpa/2021/09/06/EntityDynamicQuery/