분류 전체보기 359

MySQL - 인덱스를 사용해도 느린 이유! (key_len, filtered)

Optimizer가 원하는 Index를 사용했으면 최적의 쿼리인걸까?! 그렇지 않다! 예시를 통해 알아보자. 아래는 예시를 위해 생성한 Index이다. 아래의 쿼리를 실행시키면 어떻게 될까? explain select * from employees where office_id = 1 and money = 50; key로 custom_index가 선택되었다. 글자가 너무 작아서 중요한 부분을 확대했다. 실행 시간 해당 쿼리의 실행 시간은 548ms 이다. Index도 원하는 대로 탔고, 매우 간단한 데 쿼리임에도 불구하고 매우 오래걸린다. 뭐가 잘못된 걸까..? 1. key_len 다시 실행 계획을 보자. 여기서 가장 중요한 지표는 key_len이다. key_len은 쿼리 조건으로 사용된 인덱스 컬럼들의 ..

Database/SQL 2023.11.27

SQL - WHERE 절, ON 절 제대로 이해하기!

최근에 팀원 분이 LEFT OUTER JOIN의 ON 절에 일반 조건이 포함된 쿼리를 작성하신 것을 봤다. SELECT * FROM team t LEFT OUTER JOIN member m ON t.id = m.team_id AND m.team_id = 4; 해당 부분이 예상대로 동작하지 않을 것을 예상하고 리뷰를 드리면서, 생각보다 잘 모르시는 분이 많으실 것 같아 정리하게 되었다. 미리 말하지만 해당 SQL은 의도대로 동작하지 않는다. ON 절과 WHERE 절의 차이에 대해 알아보자. Sample Data 삽입 테스트를 위해 데이터를 삽입했다. Team을 5개 삽입 각 팀별 멤버를 2개 삽입 WHERE SELECT * FROM team t LEFT OUTER JOIN member m ON t.id =..

Database/SQL 2023.11.21

JPA - OSIV 제대로 이해하기!

OSIV(Open Session In View) OSIV(Open Session In View)는 영속성 컨텍스트를 뷰까지 개방하는 기능이다. 이를 사용하면 트랜잭션이 종료되어도 영속성 컨텍스트가 관리될 수 있다. 여기까지는 사실 다 아는 내용이고 OSIV의 동작 원리에 대해 알아보자. OpenInView Spring 환경에서 보통 아래의 property로 OSIV 설정에 접근한다. spring.jpa.open-in-view 아래는 JpaWebConfiguration 클래스의 애노테이션이다. open-in-view 속성에 따라 해당 Configuration이 등록된다는 것을 알 수 있다. 이를 통해 알 수 있는 놀라운 사실은 'Spring JPA도 웹과 연관이 있다.'는 것이다. JpaProperties..

Server/Spring JPA 2023.11.19

Spring에서의 Proxy, AOP 동작원리 이해하기!

지난번 Spring AOP를 적용하면서 생겼던 문제에 대해 소개했다. https://jaehoney.tistory.com/375 이번 포스팅에서는 실무보다는 기본 개념에 대해 집중적으로 알아보자. 해당 포스팅은 김영한님의 스프링 핵심 원리 - 고급편의 프록시 관련 내용을 정리한 것이며, 프록시와 AOP의 동작의 기본 개념이라고 보면 된다. 프록시 패턴 프록시 패턴에서는 프록시가 너무 많이 생기는 문제가 있다. 아래는 GOF 프록시 패턴의 예시이다. 예로 들면 Repository 1개마다 전부 프록시 클래스를 생성해야 한다. 프록시를 적용할 클래스가 100개라면 100개의 프록시를 적용하는 코드를 만들어야 한다. 즉, 단일 책임 원칙에 어긋나고 기능 변경 시 다수의 클래스에 변경이 전파된다. 이 문제를 해..

Server/Spring 2023.11.16

Hibernate @Where 애노테이션이 동작하지 않는 이유!

@Where 애노테이션이 동작하지 않는 이유 실무에서 Mail 일괄 수정 시 인덱스가 안타는 문제가 발생했다. 이유는 @Where(clause = "del_flag = 'N'")을 했는데, QueryDsl을 사용한 조회에서는 해당 조건을 수행하지 않아서 인덱스를 탈 수 없었다. 요즘 Hibernate 및 JPA에 대한 관심이 부쩍 늘어서 이 문제에 접근해보면 경험치를 얻을 수 있을 것 같아서 디버깅해봤다. 문제 파악 다른 코드에 대한 영향 없이 확인해야 하기 때문에 새로 프로젝트를 만들었다. 아래의 JPA Entity를 만들었다. @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @Where(clause = "name = 'violet..

Server/Spring JPA 2023.11.05

Spring의 Servlet에 X-Forwarded-For 헤더가 왜 안들어올까?!

아래는 실무 중에 만난 이슈와 해결 과정에 대해 다룬다. 정확한 원인과 해결 방법보다는 풀어나간 과정에 집중되어 있다. 원인과 해결 방안이 궁금한 분은 가장 아래로 내리시면 될 것 같습니다! 헤더에 X-Forwarded-For이 안들어오는 문제 발견 아래는 사내에서 쓰는 공통 라이브러리의 코드의 일부이다. public class SecurityHelper { static public HeaderUtil generateHeaderUtilBy(HttpServletRequest request){ return HeaderUtil.builder() .token(request.getHeader(HeaderUtil.HIWORKS_JWT_HEADER)) .clientIp(request.getHeader("X-Forwa..

Server/Spring 2023.10.26

단위 테스트 대상 분리하기!

아래는 최범균님의 유튜브를 보고 느낀 점을 나름대로 정리한 것이다. https://www.youtube.com/watch?v=qZ1R0C_iiV4 테스트 불가능한 문제 아래의 코드가 테스트가 불가능한 문제가 있었다고 한다. ResultBuilder builder = ...; InputPeriod realPeriod = mapper.selectPeriod(param); // 1. DB에서 읽음 if (realPeriod == null) { // 2. 없으면 다른 값 읽음 InputPeriod expectedPeriod = mapper.selectExpectedPeriod(otherParam); builder.period(expectedPeriod).type(EXPECTED); } else if (realP..

Accept 헤더가 포함된 REST API에서 에러를 내려주는 방법!

이번 포스팅은 회사에서 메일 원문 다운로드 API를 개발하면서 생긴 이슈에 대해 공유한다. 이해하기 쉽도록 메일 원문 대신 첨부 파일로 재해석해서 작성했다. 요즘은 파일 스토리지로 외부 인프라를 많이 사용해서 직접 설계해야 되는 상황이 드물긴 하다. 파일 접근 게시판의 첨부파일 기능을 생각해보자. 메타 데이터에는 빨간 네모와 같이 파일명과 확장자, 파일 사이즈, 다운로드 경로 등이 저장될 것이다. 다운로드를 클릭하면 실제 파일 스토리지에 접근해서 파일을 Binary 형태로 가져올 것이다. 게시판을 노출하기 위해서 메타 데이터를 가져올 때 파일 정보까지 모두 가져오면 오버헤드가 발생할 것이다. 그래서 2개의 End-point로 분리했다. Accept REST API에서는 url에 자원에 대한 경로를 지정한..

Server/Spring 2023.10.20

자바에서 동시성을 다룰 때 주의할 점!

아래는 이펙티브 자바의 내용 중 동시성에 대한 부분을 정리한 것이다. Effective Java는 동시성을 사용할 때의 몇가지 주의사항과 가이드라인을 제시한다. 동기화된 메서드 설계 시 주의할 점 동기화된 메서드를 작성할 때 중요한 것은 재정의할 수 있는 메서드를 호출해선 안되고 클라이언트가 넘겨준 함수 객체도 사용하면 안된다는 것이다. public class ObservableSet extends ForwardingSet { public void addObserver(SetObserver observer) { synchronized (observers) { observers.add(observer); } } public boolean removeObserver(SetObserver observer) {..

Language/Java 2023.10.17

Java 검사(Checked) 예외와 비검사(Unchecked) 예외

아래는 이펙티브 자바의 내용 중 예외에 대한 부분의 일부이다. 이펙티브 자바도 그렇고, 예외도 그렇고 포스팅할 내용이 너무 너무 많아서 다 정리할 수 없어서 아쉽다..! 일반적으로 검사 예외와 비검사 예외를 CheckedException, UncheckedException이라고 명명하지만, 해당 포스팅에서는 Effective Java의 명칭대로 검사 예외와 비검사 예외라고 명칭한다. 검사 예외와 비검사 예외 Throwable 클래스를 상속하는 것은 Error와 Exception이 있다. Exception을 상속하면서 RuntimeException을 상속하지 않으면 검사 예외이고, RuntimeException을 상속하면 비검사 예외라고 부른다. 참고로 Error는 Throwable을 상속하고 OutOfM..

Language/Java 2023.10.12