์๋ก
๋ณดํต ์ํฐํฐ(entity)์๋ ํด๋น ๋ฐ์ดํฐ์ ์์ฑ ์๊ฐ๊ณผ ์์ ์๊ฐ์ ํฌํจํ ์ปฌ๋ผ์ด ํญ์ ์กด์ฌํฉ๋๋ค. ์ธ์ ๋ง๋ค์ด์ก๋์ง, ์ธ์ ์์ ๋์๋์ง ๋ฑ์ ์ฐจํ ์ ์ง๋ณด์์ ์์ด ๊ต์ฅํ ์ค์ํ ์ ๋ณด์ด๋ฉฐ, ๋ฐ์ดํฐ ๋ถ์์ ์ ์ฉํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ๊ทธ๋ ๋ค ๋ณด๋ ๋งค๋ฒ DB์ ์ฝ์ (insert) ํ๊ธฐ ์ , ๊ฐฑ์ (update) ํ๊ธฐ ์ ์ ๋ ์ง ๋ฐ์ดํฐ๋ฅผ ๋ฑ๋ก/์์ ํ๋ ์ฝ๋๊ฐ ์ฌ๊ธฐ์ ๊ธฐ ๋ค์ด๊ฐ๊ฒ ๋ฉ๋๋ค.
ํ์ง๋ง ๋ชจ๋ ์ํฐํฐ๋ง๋ค ์์ฑ์๊ฐ๊ณผ ์์ ์๊ฐ์ ๋ฃ๋๋ค๋ฉด ์ฝ๋๊ฐ ๋งค์ฐ ์ง์ ๋ถํด์ง๊ณ ๊ฐ์ฒด์งํฅ์ ์ด์ง ๋ชปํฉ๋๋ค. ์ด๋ฌํ ๋ฌธ์ ๋ JPA Auditing๋ฅผ ์ฌ์ฉํ๋ฉด ์ฝ๊ฒ ํด๊ฒฐํ ์ ์์ต๋๋ค.
LocalDate ์ฌ์ฉ
Java8๋ถํฐ LocalDate์ LocalDateTime์ด ๋ฑ์ฅํ์ต๋๋ค. ์ฌ์ค ๊ทธ๋์์ Java์ ๊ธฐ๋ณธ ๋ ์ง ํ์ ์ธ Date๋ฅผ ์ฌ์ฉํด ์์ง๋ง Java8 ์ดํ๋ถํฐ๋ ๋ฌธ์ ๊ฐ ์๋ Date๋ฅผ ๊ณ ์น LocalDate์ LocalDateTime๋ฅผ ๋ฌด์กฐ๊ฑด ์ฌ์ฉํ์ ์ผ ํฉ๋๋ค.
Java8์ด ๋์ค๊ธฐ ์ ๊น์ง ์ฌ์ฉ๋์๋ Date์ Calendar ํด๋์ค๋ ๋ค์๊ณผ ๊ฐ์ ๋ฌธ์ ์ ๋ค์ด ์์์ต๋๋ค.
๋ถ๋ณ(๋ณ๊ฒฝ์ด ๋ถ๊ฐ๋ฅํ) ๊ฐ์ฒด๊ฐ ์๋๋ค.
-> ๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ์์ ์ธ์ ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๋ค.
Calendar๋ ์(Month) ๊ฐ ์ค๊ณ๊ฐ ์๋ชป๋์๋ค.
-> 10์์ ๋ํ๋ด๋ Calendar.OCTOBER์ ์ซ์ ๊ฐ์ '10'์ด ์๋๋ผ '9'๋ก ์ค๊ณ๋์ด์๋ค.
๋ฐ๋ผ์ ๊ทธ๋์ JodaTime์ด๋ผ๋ ์คํ์์ค๋ฅผ ์ฌ์ฉํด์ ๋ฌธ์ ์ ์ ํผํ์์ง๋ง, Java8 ์ดํ๋ถํฐ๋ LocalDate๋ฅผ ํตํ์ฌ ํด๊ฒฐ์ด ๊ฐ๋ฅํฉ๋๋ค.
์์ธํ ๋ด์ฉ์ ๋ค์ด๋ฒ D2์์ ์ฐธ๊ณ ๊ฐ ๊ฐ๋ฅํฉ๋๋ค. https://d2.naver.com/helloworld/645609
๋ํ LocalDate์ LocalDateTime์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ๋๋ก ๋งคํ๋์ง ์๋ ์ด์๋ Hibernate 5.2.10 ๋ฒ์ ์์ ํด๊ฒฐ๋์์ต๋๋ค. ๋ฐ๋ผ์ ์คํ๋ง ๋ถํธ 1.x๋ฅผ ์ด๋ค๋ฉด ๋ณ๋๋ก Hibernate 5.2.10 ๋ฒ์ ์ด์์ ์ฌ์ฉํ๋๋ก ์ค์ ์ด ํ์ํ์ง๋ง, ์คํ๋ง ๋ถํธ 2.x ๋ฒ์ ์ ์ฌ์ฉํ๋ฉด ๊ธฐ๋ณธ์ ์ผ๋ก ํด๋น ๋ฒ์ ์ ์ฌ์ฉ ์ค์ด๋ผ ๋ณ๋ค๋ฅธ ์ค์ ์์ด ๋ฐ๋ก ์ ์ฉํ๋ฉด ๋ฉ๋๋ค.
์์
@Getter
@MappedSuperclass // BaseEntity๋ฅผ ์์ํ ์ํฐํฐ๋ค์ ์๋ ํ๋๋ค์ ์ปฌ๋ผ์ผ๋ก ์ธ์ํ๊ฒ ๋๋ค.
@EntityListeners(AuditingEntityListener.class) // Auditing(์๋์ผ๋ก ๊ฐ ๋งคํ) ๊ธฐ๋ฅ ์ถ๊ฐ
public abstract class BaseTimeEntity {
@CreatedDate
private LocalDateTime createdTime;
@LastModifiedDate
private LocalDateTime lastModifiedTime;
}
๋จผ์ BaseTimeEntity๋ฅผ ์ถ์ ํด๋์ค ํํ๋ก ์์ฑํฉ๋๋ค. BaseTimeEntity ํด๋์ค๋ ๋ชจ๋ Entity์ ์์ ํด๋์ค๊ฐ ๋์ด Entity๋ค์ ์์ฑ ์๊ฐ๊ณผ, ์์ ์๊ฐ์ ์๋์ผ๋ก ๊ด๋ฆฌํ๋ ์ญํ ์ ๋๋ค.
๊ฐ ์ฝ๋์ ์ด๋ ธํ ์ด์ ์ ์ค๋ช ํ๋ฉด ์๋์ ๊ฐ์ต๋๋ค.
- @MappedSuperclass: JPA Entity ํด๋์ค๋ค์ด BaseTimeEntity์ ์์ํ ๊ฒฝ์ฐ ํ๋๋ค(createdTime, lastModifiedTime)๋ ์ปฌ๋ผ์ผ๋ก ์ธ์ํ๋๋ก ํฉ๋๋ค.
- @EntityListeners(AuditingEntityListener.class): BaseTimeEntity ํด๋์ค์ Auditing ๊ธฐ๋ฅ์ ํฌํจ์ํต๋๋ค.
- @CreatedDate: Entitiy๊ฐ ์ต์ด๋ก ์์ฑ๋์ด ์ ์ฅ๋ ๋ ์๊ฐ์ด ์๋์ผ๋ก ์ ์ฅ๋ฉ๋๋ค.
- @LastModifiedDate: ์กฐํํ Entity์ ๊ฐ์ ๋ณ๊ฒฝํ ๋ ์๊ฐ์ด ์๋์ผ๋ก ์ ์ฅ๋ฉ๋๋ค.
@Entity
@AllArgsConstructor
@NoArgsConstructor
public class User extends BaseTimeEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
private String password;
@Builder
public User(String name, String password) {
this.name = name;
this.password = password;
}
}
๊ทธ ํ Entity ํด๋์ค์ธ User๊ฐ BaseTimeEntity๋ฅผ ์์๋ฐ๋๋ก ์์ฑํฉ๋๋ค.
@SpringBootApplication
@EnableJpaAuditing
public class ApiPracticeApplication {
public static void main(String[] args) {
SpringApplication.run(ApiPracticeApplication.class, args);
}
@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver localeResolver = new SessionLocaleResolver();
localeResolver.setDefaultLocale(Locale.KOREA);
return localeResolver;
}
}
๋ง์ง๋ง์ผ๋ก JPA Auditing ์ด๋ ธํ ์ด์ ๋ค์ ๋ชจ๋ ํ์ฑํํ ์ ์๋๋ก Apllication ํด๋์ค์ ์์ ๊ฐ์ด ํ์ฑํ ์ด๋ ธํ ์ด์ ์ธ @EnableJpaAuditing์ ์ถ๊ฐํฉ๋๋ค.
ํ ์คํธ
@SpringBootTest
class UserTest {
@Autowired
private UserRepository userRepository;
@Test
void BaseEntity_ํ
์คํธ(){
// given
LocalDateTime nowTime = LocalDateTime.now();
User user = User.builder()
.name("์์ฃผํ")
.password("password1")
.build();
//when
userRepository.save(user);
//then
assertThat(user.getCreatedTime()).isAfter(nowTime);
}
ํ ์คํธ ์ฝ๋๋ ์์ ๊ฐ์ต๋๋ค. nowTime์ userํด๋์ค๊ฐ ์์ฑ๋๊ธฐ ์ด์ ์ ์ ์ฅ๋๊ธฐ ๋๋ฌธ์ userํด๋์ค์ createdTime ๋ณด๋ค ํญ์ ์๊ฒ ๋์์ผ ํ ๊ฒ์ ๋๋ค. ๋ฐ๋ผ์ assertThat(user.getCreatedTime()).isAfter(nowTime); ์ ํตํด ๊ฒ์ฆ์ ํ ๊ฒ์ ๋๋ค.
ํ ์คํธ ์ํ๊ฒฐ๊ณผ๋ ์์ํ๋ ๋๋ก ๋ฌด์ฌํ ํต๊ณผ๋์์ต๋๋ค.
์ฐธ๊ณ
์คํ๋ง ๋ถํธ์ AWS๋ก ํผ์ ๊ตฌํํ๋ ์น ์๋น์ค(3.5์ฅ) - ์ด๋์ฑ
'BackEnd๐ฑ > Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Spring] StringUtils ์ ์ฉํ ๋ฉ์๋ ์ ๋ฆฌ (0) | 2022.08.31 |
---|---|
AssertJ ํต์ฌ ๊ธฐ๋ฅ ์์๋ณด๊ธฐ (1) | 2022.08.08 |
[Querydsl] unable to load class com.mysema.codegen.model.type'. error (1) | 2022.07.31 |
[Spring] @Valid, @ControllerAdvice, @Exception์ ์ด์ฉํ ๋ฐ์ดํฐ ๊ฒ์ฆ ๋ฐ ์ฒ๋ฆฌ (0) | 2022.05.20 |
[Spring] nested exception is java.lang.NullPointerException (0) | 2022.05.15 |
[Spring] ๊ฐ์ฒด๋ณต์ฌ BeanUtils.copyProperties (0) | 2022.05.15 |
๋๊ธ