• spring boot mongo DB LocalDateTime UTC -> KST 한국 시간 전환하기

    서론 spring에서 mongo DB에 Document의 LocalDateTime 필드를 저장하면 UTC의 시간으로 변환되어 들어간다. 아마 팀 컨벤션에 따라 다를 것 같은데, 우리는 mongo DB에서도 KST 한국 시간으로 보고 싶었다. 따라서 covnerter를 만들기로 했다. 기본적인 베이스는 spring이 제공하는 Spring Data MongoDB에 커스텀 컨버터를 추가하는 것이다. https://docs.spring.io/spring-data/mongodb/reference/mongodb/mapping/custom-conversions.html Custom Conversions :: Spring Data MongoDB Generally, we inspect the Converter imple..

  • 코틀린 default 생성자 만들기

    코틀린 default 생성자 만들기

    개요 코틀린으로 Spring boot를 다루다보면, 기존 자바로 되어있는 프레임워크 로직이 가끔씩 에러를 일으킨다. FlatFileItemReader를 사용하려다가 에러가 났는데, Target class를 Data class로 잡아놨었다. Bean 생성에 대한 에러 메시지였는데.. FlatFileItemReader의 다음과 같은 특성때문이었다. 1. FlatFileItemReader는 Target Class의 인스턴스를 Default 생성자를 통해 생성한다. 2. 후에 파일을 파싱하여 인스턴스의 필드의 setter를 이용해 값을 주입한다. 따라서 코틀린으로 해당 Target Class를 만드려면 Default 생성자와 Setter를 만들어줘야 하는것이다. 해결 코틀린은 변수를 val로 선언하기를 권장한다..

  • CompositeCacheManager의 배치 시간 소요 문제 - CacheManager는 꼭 전부 Bean 등록하자

    CompositeCacheManager의 배치 시간 소요 문제 - CacheManager는 꼭 전부 Bean 등록하자

    문제 얼마전 회사에서 local cache와 redis를 같이 쓰도록 바뀌었는데, 이 때 CompositeCacheManager를 사용했다. @Bean fun cacheManager(): CacheManager = CompositeCacheManager().apply{ setCacheManagers(listOf(getCaffeineCacheManager(), getRedisCacheManager)) } fun getCaffeineCacheManager(): SimpleCacheManager = SimpleCacheManager().apply{ setCaches(...) } fun getRedisCacheManager(): RedisCacheManager = RedisCacheManager.builder(..

  • Redis Jackson @JsonUnwrapped Unwrapped property requires use of type information 이슈

    이슈 코틀린을 사용하면서 Redis에서 value에 직렬화/역직렬화 클래스를 설정할 일이 있어 해당 구현체로 Jackson을 사용하기로했다. 그래서 ObjectMapper를 커스텀해서 사용하던 도중 어느 한 dto data class를 직렬화할때 에러가 났다. Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Unwrapped property requires use of type information: cannot serialize without disabling `SerializationFeature.FAIL_ON_UNWRAPPED_TYPE_IDENTIFIERS` 해당 dto의 프로퍼티는 클래스였고, @JsonUnwrap..

  • 참조(Reference) vs 포인터

    참조와 포인터는 똑같다. C++에는 참조와 포인터가 있는데, 이 둘은 표현 방식이 다르지만 내부 동작은 똑같다. 다른 점은 ? 참조가 포인터보다 사용하기 편하다. 만약 함수의 인자로 포인터를 받기로 했다면 어떤 변수의 주소를 받았을텐데.. 이 변수를 사용하려면 *을 붙이는 등 귀찮다. 하지만 참조는 그냥 실제 변수처럼 사용하면 된다. 다만, 이 점때문에 포인터는 확실하게 원본을 넘긴다는 힌트를 줄 수 있는데, 참조는 놓칠 수 있다. (가독성 문제) 결론 정해진 답은 없다.. 스스로 컨벤션을 정하거나 팀과 컨벤션을 정하여 참조 or 포인터 사용을 정하는 것이 정답...~

  • oracle insert all vs insert into ~ union all 왜 union all이 빠른가

    oracle insert all vs insert into ~ union all 왜 union all이 빠른가

    insert all vs insert into ~ union all oracle에서 많은 양의 row을 한 번에 입력할 일이 있어서 처음에 insert all을 사용했다. insert all을 사용하는 문장은 다음과 같다. insert all into dummy(id, col1, col2, col3) values (1001,'30841','30842','30843') into dummy(...) values (...) ... select * from dual; 처음엔 이 문장이 mysql의 insert into values()... 와 비슷하게 생겼길래 그냥 갖다썼다. 근데 알고보니 성능이 떨어진다고 한다. union all 을 이용한 insert into가 훨씬 더 빠르다는 것이다. union all을..

  • MySQL varchar(255)를 사용하는 이유?

    이유 MySQL에서 테이블을 만들 때 varchar(255)를 자주 사용했다. varchar가 가변길이 타입으로 char에 비해 실제 저장한 데이터의 크기만큼 저장한다고 알고 있었다. 그런데 왜 하필 255인지는 생각해본 적이 없어 알아보았다. MySQL 8.0의 공식 문서를 보면 다음과 같이 적혀있다. Values in VARCHAR columns are variable-length strings. The length can be specified as a value from 0 to 65,535. The effective maximum length of a VARCHAR is subject to the maximum row size (65,535 bytes, which is shared among a..

  • sync, async, blocking, non-blocking

    서론 얼마 전에 면접에서 이 개념들을 섞어서 대답하는 바람에... ㅠㅠ 이번에 확실히 정리하고자 글을 쓴다. blocking, non-blocking 이 두 개의 개념은 어떤 한 함수가 어떻게 동작하는지에 관한 이야기다. 함수 A와 B가 존재한다고 하자. 그리고 함수 A가 코드 안에서 함수 B를 호출한다. 이 때 함수 A가 어떻게 행동할지에 따라서 blocking과 non-blocking이 결정된다. 함수 B에는 관심이 없다. 여기서 함수 A의 동작에만 초점을 맞춰보자. blocking에서 함수 A는 다른 행동을 하지 않고 함수 B의 결과를 기다린다. 그러면 함수 A와 함수 B는 싱글 프로세스, 싱글 쓰레드, 멀티 프로세스, 멀티 쓰레드 중에 무엇일까? 모른다. 이것은 구현에 관한 이야기다. 어떤 것으로..

  • Spring boot Docker image 제작하여 EC2 배포하기

    Spring boot Docker image 제작하여 EC2 배포하기

    Dockerfile 만들기 Dokcer image를 제작하려면 먼저 image를 어떻게 만들지 명령어가 적혀있는 Dockerfile을 만들어야한다. 확장자가 없는 파일이고 원하는 경로에다가 저장하면 된다. 나는 프로젝트 루트에 저장했다. touch Dockerfile 이후 Dockerfile이 생성되면, 몇 가지 명령어를 Dockerfile에 적어야한다. 텍스트 편집기나 IDE를 이용한다. 먼저, base가 될 image를 선택해야한다. docker hub에 가보면 사람들이 올려놓은 base image가 있다. 이 중 하나를 선택하면 되는데, 내 프로젝트는 java 11을 사용하므로 openjdk의 java 11 버전의 이미지를 사용할 것이다. 나중에 docker hub에 이미지를 업로드 할 것이기 때문..

  • read commited와 repeatable read 차이점

    헷갈리는 차이점 두 격리 수준에 대해 헷갈렸는데 정리해보고자 한다. BEGIN TRANSACTION; SELECT * FROM T; WAITFOR DELAY '00:01:00' SELECT * FROM T; COMMIT; 한 트랜잭션이 위 쿼리문을 실행한다고 하자. SELECT * FROM T; 를 실행하고 1분 후 다시 SELECT * FROM T; 를 실행하는 쿼리다. read commited에서는 커밋된 어떤 데이터든 볼 수 있다. 첫 번째 SELECT * FROM T; 이후에 기다리던 1분 동안 동시에 실행되던 다른 트랜잭션들이 해당 테이블의 데이터를 추가, 수정, 삭제하고 커밋한다면 해당 내용이 반영된다. 따라서 두 번째 SELECT * FROM T;를 실행했을 때 첫 번째와 결과가 달라질 수 ..