반응형

개발 330

[Spring] 사용자의 데이터 변경 이력 관리

개발을 하다가 문득 사용자의 추천 설정과 같은 정보들의 변경 이력을 관리하고 있지 않고 있었다라는 것을 깨달았다. 예상되는 문제는 사용자에게 추천을 했는데 로직 상 문제 없는 추천에 대해서 사용자가 착각해서 이거 왜 추천되나요? 라고 했을 때이다. 이 유저가 추천 설정이 C 라고 돼 있을 때, 신고 당시 A 였는지 B 였는지 계속 C인 상태였는지 파악이 되지 않아 파악에 굉장히 어려울 것 같았다. 처음에는 아래와 같은 테이블로 작업을 할까 했었다. 왜냐하면 제일 간단하다고 생각했고, 해당 테이블 하나로 여러 데이터의 변경 이력을 관리할 수 있으니까 관리 포인트도 줄일 수 있을 것 같았다. id user_id target before create_date pk 변경 필드 변경 전 데이터 그러나 http p..

개발/Spring 2021.01.13

[Spring] 코틀린 data class 사용 시 retrofit 에서 @JsonProperty 가 적용되지 않을 때

사용하고 있는 retrofit 의 버전은 각각 다음과 같다. - retrofit 2.3.0 - converter-jackson 2.3.0 분명 JacksonConverterFactory 를 추가해주었는데도 적용이 안됐다. kotlin data class 에서 @JsonProperty 가 적용되기 위해 해당 의존성을 추가해서 사용하고 있었다. 그리고, retrofit 문서에서 나와있는 대로 converter 를 추가하기 위해 다음과 같은 의존성을 또 추가 해 주었다. 여기서 나는 retrofit 에서 제공하는 jackson-converter 에는 기본적으로 kotlin 을 위한 설정이 돼 있지 않다고 생각이 들었다. 그래서 retrofit 의 jackson converter 에서만 KoltinModule ..

개발/Spring 2020.12.27

select 에도 transaction 걸어야 하는 이유

예전에 막 개발을 시작했을 때 spring 에서 @Tramsactional 이라는 어노테이션을 단순 select 에서도 적용하는 것을 보고 궁금했었다. 이번에 Real Mysql 책을 보다가 비슷한? 내용이 나왔다. 트랜잭션 내에서 실행되는 SELECT 문장과 트랜잭션 없이 실행되는 SELECT 문장의 차이는 READ COMMITTED 격리 수준에서는 차이가 별로 없다. 그러나 REPEATABLE READ 격리 수준에서는 트랜잭션 동안에 다른 트랜잭션에서 아무리 특정 데이터를 변경하고 커밋하더라도 동일한 결과를 보게 된다. 그렇기 때문에 격리 수준에 따라서 동작이 달라진다. 위의 현상을 non-repeatable read 라고 한다. read committed 일 때는 특정 트랜잭션 내에서 A 데이터를 ..

[Spring Batch] no job configuration with the name was registered

'sync' 라는 job 을 생성하고 jobLocator 를 이용하여 job 을 가져오려고 하는데 계속 해당 에러가 발생했다. no job configuration with the name 'sync' was registered 우선 Spring Batch 에서 JobRegistry 라는 클래스를 제공해주고 있다. 해당 JobRegistryBeanPostProcessor 클래스도 제공하는데 job 들을 설정한 jobRegistry 에 등록시켜주는 친구인 것 같다. 네이밍도 Post Processor 인 것으로 보아 application context 올라가고 job 으로 등록된 bean 들을 jobRegistry 에 등록시켜 주는 것으로 이해하면 될 것 같다. @Configuration class Job..

개발/Spring 2020.12.01

좋지 않은 테이블 구조에서의 개발

좋지 않은 테이블 구조에서의 개발을 어떻게 해야할까..? 좋지 않은 테이블 구조라고 했는데 우선 정합성이 다 깨져버려있다는 것을 의미하고 있다. 그리고 특정 A, B 테이블의 의존관계가 1 : N 이 될 수도 있고, 1 : 1 이 될 수도 있다. 백엔드에선 JPA, querydsl 을 사용해서 의존관계 맺어서 one to one, one to many 등을 이용해서 각 기능들을 구현하고 있었다. 그런데 테이블 구조가 썩 좋진 않다보니 쉽게 개발하려고 JPA 를 사용하는데 비즈니스 코드가 너무 복잡해지거나, 테이블 구조가 이상한데 이걸 다시 코드로 구현하자니 코드도 썩 좋지 않게 되는 것 같았다. 그래서 우선 각 엔티티 별로 모두 다 쪼개고 의존관계 맺지 않고 무조건 코드에서 각 엔티티를 조합해서 사용하는..

[Spring] gc overhead limit exceeded 원인 찾기

서버에서 gc overhead limit exceeded 라는 에러를 내뿜었다. 검색해보니 우선 해당 에러는 CPU 사용량중 98%이상이 GC가 작동되는 경우 gc overhead limit exceeded 가 발생이 된다고 한다. 이런 상황은 처음이라서 굉장히 당황했고 나 혼자 서비스 개발을 하니 주변 사람에게 물어볼 수도 없었다. 우선 그래서 ec2 인스턴스에 접속해서 힙덤프를 떴고 MAT 이란 memory analyzer 를 이용해서 확인을 해 보았다. hibernate 의 SessionFactoryImpl 이라는 오브젝트가 무려 589MB 나 했다. 도큐먼트에 나와있는 SessionFactoryImpl 에 대한 설명이다. Concrete implementation of the SessionFact..

개발/Spring 2020.10.12

클래스 명에 상위 패키지 명이 들어가야 될까

클래스 명에 상위 패키지 명이 들어가야 할까? 에 대한 얘기를 해보려고 한다. - com.hojak.test - service - recommend - RecommendBookService.class 내가 진행하고 있는 프로젝트에 패키지 구조가 이렇게 돼 있다고 해보자. recommend 패키지 내에 `RecommendBookService` 클래스가 존재한다. 회사 시니어 개발자분께서 굳이 `RecommendBookService` 클래스 이름에 `Recommend` 라는 단어를 붙일 필요가 있는가? 라는 이야기를 해 주셨다. 이미 패키지에서 `recommend` 라고 표현하고 있는데 굳이 클래스에서 또 `recommend` 라는 단어를 사용할 필요가 있냐는 이야기신 것 같다. 그래서 생각해보니 굳이,,?..

레이어 분리 (deprecated)

지금 보니 좀 문제가 있어 보인다. DTO 로 convert 하는 식으로 하면 JPA 를 사용하는 이유가 없어진다. 애초에 서로 도메인의 경계를 잘 나누면 된다. 그래도 옛날의 나의 생각이었기에 글은 냅두도록 한다. 개발을 하다 보면 레이어 분리를 어떻게 해야 잘 하는지에 대한 고민을 하게 된다. 모놀리틱에서 개발을 한다고 했을 때 보통 나는 다음과 같은 레이어로 분리를 하여 개발을 하게 된다. - serivce - repository - domain - controller 일반적인 jpa + spring 사용 시에 나오는 패키지 구조이다. presentation, business, persistence 레이어로 분리했다고 볼 수도 있을 것 같다. service 클래스에서는 repository 나 다른 ..

[Spring] Slice Test

나는 테스트에 대해서 공부할 때 통합 테스트, 단위 테스트라는 단어를 많이 들었다. 그래서 내가 필요하다고 생각할 때 단위 테스트를 작성하고 좀 큰 기능인 것 같으면 통합 테스트를 이용해서 전체적인 흐름을 테스트를 하고 있다. Slice Test 최근에 Mockito 라이브러리를 이용한 mock 을 주입해서 테스트를 하던 중, 슬라이스 테스트라는 용어를 알게 되었다. Test slicing is about segmenting the ApplicationContext that is created for your test spring.io 에 따르면 위와 같이 소개를 하고 있다. https://spring.io/blog/2016/08/30/custom-test-slice-with-spring-boot-1-4..

개발/Spring 2020.08.12

jwt 사용 시 refresh token 은 어떻게 관리해야 할까

개인적으로 진행하는 프로젝트에 로그인 보안에 jwt 을 이용하려고 하고 있다. 이 때 jwt 사용 시 refresh token 은 어디서 관리해야 할까에 대해서 굉장히 많은 고민을 했다. refresh token 은 어디서 관리해야 할까? 우선 토큰 사용의 목적은 stateless 하게 가져가기 위함이다. 세션을 사용한다면 매 요청마다 redis 든 DB 든 어디선가 세션 정보를 저장하고 있고, 이 세션이 올바른지 체크를 하게 된다. 이 때 토큰을 사용 시 토큰이 유효한가? 에 대해서만 체크하면 되는데 이 때 access token 과 refresh token 으로 관리를 하게 된다면 access token 으로 유효성 검증 후 access token 내에 만료 시간 데이터를 넣어서 매 요청마다 단순히 ..

반응형