전체 글 100

Java > 패키지 구조

Layer-based 구조 (계층별 구조)com.example.app ├─ controller │ ├─ UserController.java │ └─ ProductController.java ├─ service │ ├─ UserService.java │ └─ ProductService.java └─ dao ├─ UserDao.java └─ ProductDao.java 장점계층 책임이 명확함MVC 패턴과 직관적으로 매칭단점도메인 단위로 변경/확장하기 어렵고, 특정 기능 수정 시 여러 패키지를 오가야 할 수 있음규모가 커지면 패키지 간 의존성 관리가 어려움 Feature/Domain-based 구조 (도메인별 구조)com.example.app ├─ user │ ├─ UserCo..

Java/Java > Basics 2025.11.17

Git > Branch > 특정 브랜치에서 일부 코드만 배포 필요한 경우

예를 들어 b1 브랜치에서 m1, m2 모듈의 코드 수정이 발생했는데, 이번 배포에서 m2 모듈만 배포가 필요한 경우가 있을 수 있다. 이 경우, b1 브랜치를 배포하면 문제가 되기 때문에 m2 모듈의 코드 수정분만 담긴 b2 브랜치를 만들어야 한다 cherry-pick으로 필요한 커밋만 따오기기존 커밋 이력 유지 가능 b1 브랜치에서 커밋 이력 확인git log --onelinem2 모듈 관련 커밋 ID를 확인한다develop에서 새 브랜치 생성git checkout developgit pullgit checkout -b feature/b2m2 모듈 관련 커밋만 cherry-pickgit cherry-pick abc123 def456IntelliJ IDEA에서 하는 법develop에서 새 브랜치 생성(..

Git 2025.11.05

Freemarker > 숫자 형식 설정

문제프리마커에서는 아래와 같이 Preset을 제공하며 number가 기본값이다number가 기본값이므로 화면단에서 값을 바인딩하였을 때 숫자가 천이 넘으면 ,가 포함되어 연동 코드에서 버그 유발 가능성이 있음예를 들어 파라미터의 값에 ,가 포함된 숫자가 설정된다거나.. 해결@Configurationpublic class FreeMarkerConfig { public FreeMarkerConfig(freemarker.template.Configuration configuration) { configuration.setNumberFormat("computer"); }} 위와 같이 computer로 설정하여 무조건 숫자로 출력되게 하고, UI에서 천단위 구분이 필요하다면 아래와 같이 사..

MySQL > COUNT 함수의 파라미터에 따른 성능 차이

COUNT(*), COUNT(1), COUNT(칼럼명) 중 어느 걸 사용해야 성능에 좋을까?에 대한 궁금증을 해소하기 위해 작성 COUNT(*)NULL 값 여부와 상관없이 테이블의 모든 행을 센다 MySQL 옵티마이저가 COUNT(*)를 위해 특수 최적화를 하기 때문에 가장 빠르다실제로는 특정 칼럼을 읽지 않고, 단순히 행의 수만 계산(인덱스만으로 계산 가능) COUNT(1)각 행마다 1이라는 상수를 평가하고, 그 결과가 NULL이 아니므로 결국 모든 행을 센다 COUNT(*)와 사실상 동일 COUNT(칼럼명)지정된 칼럼이 NULL이 아닌 행만 센다 NULL 판별로 인해 상대적으로 느리다(인덱스가 있다면 인덱스에서 NULL 여부만 확인하므로 어느 정도 빨라질 수는 있다)

RDBMS 2025.10.15

JPA > 문제 해결

Caused by: org.hibernate.query.SemanticException: Fetch join has a 'with' clause (use a filter instead)Fetch join 시 with/on 절을 사용했더니 발생-> Where 절에서 필터링 해야함 페치 조인은 객체 그래프를 함께 로딩하기 위해 사용하는 건데, on 조건을 사용하면 연관 엔티티의 일부만 조인되므로, 영속성 컨텍스트에 불완전한 객체가 들어갈 수 있어 위험 이게 무슨말이냐면, Post 엔터티가 Comment 컬렉션 엔터티를 가지고 있을 때, JPQL에서 Comment의 deleted = false로 조회하였다면, 나중에 post.getComments()를 호출해도 deleted = true인 것은 조회되지 않음...

Spring/JPA 2025.05.26

Spring > 전역 예외 처리기의 최상위 예외 클래스 처리 메서드에서 잡지 못하는 예외가 있다?

문제@RestControllerAdvicepublic class GlobalExceptionHandler extends ResponseEntityExceptionHandler { @ExceptionHandler(Exception.class) public ResponseEntity handleException(Exception e) {... 위와 같은 전역 예외 처리기가 있다고 하자. 클라이언트에서 요청을 하였는데 400 응답 코드를 가진 응답을 받았는데, 서버에서는 로그가 찍히지 않는다. 클라이언트가 받은 응답에서는 원인을 나타내는 실마리가 없었다. 분석 및 해결서버 로그 레벨을 변경해보자logging: level: org.springframework.web.method.HandlerM..

Spring 2025.05.15

Bean Validation > 컬렉션에 애너테이션 설정 시 미동작

문제 1. 컬렉션에 @Size(min = 1)을 설정했는데 값을 전달하지 않았는데(null인데도) 유효성 검증이 되지 않음이유는 @Size는 not null 확인을 하지 않기 때문 @NotNull@Size(min = 1)위와 같이 설정하거나 @NotEmpty만 사용해야 함 문제 2. 클래스 내에 컬렉션 필드가 있을 때 해당 필드에 애너테이션을 설정해도 유효성 검증되지 않음이유는 Generics를 사용하면 Runtime에는 타입 정보가 없어지기 때문 private List users;위와 같이 설정해야 함

Spring > Cache > @Cacheable로 저장되는 데이터 자료구조

@Cacheable(cacheNames = "user") // @Cacheable("user")와 동일public User readUserById(String id) 이렇게 설정했고 메서드 호출 시 파라미터를 1로 넘겼다면, 레디스에 캐시 키는 어떻게 저장될까? > KEYS1) "user::1" 이때 해당 키는 레디스에 어떤 자료구조로 저장될까?> TYPE user::1string @Cacheable은 단순 key → value 캐싱 구조이며, 레디스에 저장될 때도 보통 직렬화된 객체를 문자열로 저장한다. 즉, @Cacheable로는 Redis의 Hash 구조를 직접 활용하지 못한다. RedisTemplate을 직접 사용해야 한다 HashOperations를 사용하여 저장한 경우는 아래와 같이 저장된다>..

Spring/Cache 2025.05.08