Skills

Skills/Java & Spring

hibernate 6.2 timezone 이슈

현상ZonedDateTime 타입의 컬럼에 ZonedDateTime.now() 값 저장시 현재 시간보다 9시간 빠른 시간으로 저장 됨JPA DB insert log 에서는 현재 시간으로 저장 요청을 하지만, 실제 DB에는 9시간 빠른 시간으로 저장된 것을 확인 원인Spring Boot 3.1 버전부터 Hibernate 6.2 버전이 적용되는데, 6.2 버전에서 OffsetDateTime, ZonedDateTime 사용시 timezone 을 다루는 방식이 변경되면서 생긴 현상변경된 시간대(timezone) 정보를 다루는 방식내부적으로 TimeZoneStorageType 값과 매핑하여 저장 및 조회 로직이 결정됨기본값은 TimeZoneStorageType.DEFAULTDB 컬럼이 시간대 정보를 저장하면 시간..

Skills/Java & Spring

java 의 Date 와 Time

1. java의 날짜와 시간 클래스 변천사1. java.util.Date (java 1.0)날짜를 의미하는 Date라는 클래스의 이름과 달리 특정 시점을 날짜가 아닌 밀리초 단위로 표현1900년을 기준으로 하는 오프셋, 0에서 시작하는 달 인덱스 등 모호한 설계로 유용성이 떨어짐ex) 2017년 9월 21일을 가르키는 Date 인스턴스를 만드는 코드 (자바 9가 나온 날짜..) Date date = new Date(117, 8, 21);// 출력 결과// Thu Sep 21 00:00:00 KST 2017 2. java.util.Calendar (java 1.1)Date 클래스의 여러 메서드를 deprecated 하고 대안으로 나온 클래스0에서 시작하는 달 인덱스가 변하지 않음DateFormat 등의 클..

Skills/Database

spring data envers

1. hibernate envers?Hibernate Envers : Hibernate를 기반으로하는 객체 레벨의 데이터 변경 추적 및 버전 관리 도구이를 사용하면 엔티티의 변경 이력을 추적하고, 각 변경 내용을 버전 관리하여 데이터를 효과적으로 관리할 수 있음별도의 변경 로그 또는 이력 관리 시스템을 구현할 필요 없이 자동으로 데이터 변경 이력을 관리해준다는 장점envers 에서 제공하는 기능들REV / REV_TYPEREV : 순번 시퀀스REV_TYPE : 0은 생성, 1은 수정, 2는 삭제REV(Revision)의 경우 트랜잭션 단위로 저장도 가능(로우를 여러개 수정 했을 때 같은 revision 을 넣을 수도 있다)annotation@Audited - 히스토리 관리 필드(혹은 클래스)@NotAud..

Skills/Database

RedisCommandExecutionException: ERR invalid expire time in setex 오류와 공식 문서 살펴보기

RedisCommandExecutionException 오류 발생! 며칠 전, 내가 개발한 기능과 관련하여 Redis 저장 시 오류가 발생하였다.해당 기능을 간단히 설명하자면 현재 시간과 자정의 시간을 비교하여 초 차이만큼을 TTL로 설정하는 특수한(?) 스펙을 가지고 있다.그래서 6시에 API 요청을 하는 사용자와 9시에 API 요청을 하는 사용자가 서로 다른 TTL을 가지게 된다.데이터독을 살펴보니 23시 59분 59초에 조회한 사용자에게서 해당 오류가 발생했다. 사실 이 부분에 있어서 테스트를 분명 작성해두었는데 오류가 발생해서 조금 당황스러웠다.다행히도 자정 이후에 다시 시도하여 이슈가 해결은 되었으나점점 해당 기능을 사용하는 사용자가 많아지면 동일한 이슈가 또 발생할 가능성이 높았기 때문에 원인..

Skills/Java & Spring

Java의 Reflection과 JPA 엔티티의 기본 생성자 protected를 권장하는 이유

Reflection? java에서는 reflection이라는 api를 제공한다. reflection은 구체적인 클래스 타입을 알지 못해도 클래스의 메서드나, 타입, 변수들에 접근할 수 있도록 해주는 api이다 대표적인 적용 예시로는 1) JPA에서 객체 조회시 데이터가 들어가는 것 2) @RequestBody 사용 시 DTO 객체에 데이터가 들어가는 것 3) 테스트 케이스 작성시 private 메서드를 테스트할 때 등이 있다. 어떻게 가능한걸까? 기본적으로 객체에 데이터를 넣기 위해서는 일련의 과정(new, setter 등)이 필요하고, 접근 제어자에 따라 접근이 불가능한 것이 맞다. 하지만 reflection이 적용된다면 이러한 과정이 필요하지 않고 private 메서드의 접근도 가능하다. 바로 ref..