본문 바로가기

Spring61

비동기 환경에서 Spring Security 로그인 정보를 유지시키는 방법 Spring에서는 비동기 처리를 위해 @Async 어노테이션이나 CompletableFuture를 자주 사용한다. 하지만 비동기적으로 실행되는 코드에서는 SecurityContextHolder에 저장된 인증 정보(Authentication)가 기본적으로 전파되지 않기 때문에 보안 컨텍스트를 유지하는 것이 문제가 될 수 있다. 해당 포스트에서는 이 문제를 해결하는 방법을 예제와 함께 설명한다.왜 비동기 환경에서 SecurityContext가 유지되지 않을까?Spring Security는 현재 스레드에 보안 컨텍스트를 저장한다. 하지만 @Async나 CompletableFuture를 사용하면 새로운 스레드가 생성되어 비동기 작업이 수행된다. 이때, 기본적으로 새로운 스레드에는 원래 스레드의 보안 컨텍스트가 .. 2024. 9. 2.
비동기 프로그래밍 @Async와 CompletableFuture 비동기 프로그래밍의 두 가지 접근법비동기 프로그래밍은 현대 애플리케이션에서 성능을 최적화하고 사용자 경험을 향상하기 위해 필수적인 기술이다. Java에서는 비동기 프로그래밍을 지원하는 여러 도구가 있으며, 그중에서도 Spring Framework의 @Async 어노테이션과 Java 표준 라이브러리의 CompletableFuture가 많이 사용된다. 그러면 어떤 경우에 @Async를 사용하고 CompletableFuture를 사용해야 할까? 해당 포스트를 통해 @Async와 CompletableFuture의 차이점과 각각의 사용 사례를 구체적으로 살펴보자. @Async - Spring의 간편한 비동기 처리@Async는 Spring Framework에서 제공하는 어노테이션으로, 메서드를 비동기적으로 실행할 .. 2024. 8. 29.
JPA Buddy 플러그인을 이용해서 엔티티에 equals와 hashcode를 명시적으로 구현해야 하는 이유 개발하다 보면 엔티티에 equals, hashcode를 구현하기 위해 Lombok 라이브러리를 활용해 @EqualsAndHashCode를 사용하는 경우가 있다. 하지만 이전 포스팅에서 다뤘던 것처럼 Lazy 연관관계를 갖는 엔티티에서  @EqualsAndHashCode를 사용하면 실제 동등성 비교와 테스트 코드에서 문제가 발생할 수 있다. https://shiba-holic.tistory.com/64 JPA에서 Lombok 사용시 주의할 점🤣 배경 프로젝트를 마치고 나면 항상 코드 인스펙션 과정을 통해 프로그램에 대한 취약점이나 장애가 있는지 확인을 하게 되는데, 간혹 equals와 hashcode가 구현되지 않은 엔티티에 대해 경고로shiba-holic.tistory.com이런 경우, 기본 Lombo.. 2024. 6. 22.
[Querydsl] @OneToMany에서 조건 절과 Fetch Join을 함께 사용할 때 서브쿼리 사용하기 배경프로젝트에서 동적 쿼리가 필요한 요구사항을 처리하기 위해 Querydsl를 사용하게 되었다. 쿼리 호출을 최소화하기 위해 1:N 연관관계로 되어있는 데이터를 페치 조인(fetchJoin)으로 가져오려고 했으나, 생각대로 되지 않았다. 필요한건 연관된 목록 전체의 정보인데, 조건에 맞는 데이터 한 건만 가지고 오게 되는 것이었다. 아래는 동일한 상황을 간단하게 재연한 것이다.Shiba@Entity@Table(name = "tb_shiba_holic")@Getterpublic final class Shiba { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "seq") private Long seq; .. 2024. 5. 12.
Controller에서 의존성 주입 대상 필드 값이 NULL이 되는 문제와 해결방안, 이유 👋 배경 컨트롤러 매핑 메서드에서 의존성 주입된 필드에 접근하는데, 해당 필드가 null로 되어서 NullPointException이 뜨는 상황이 발생했다. 의존성 주입 대상 필드는 컴포넌트 스캔 범위에도 포함되어 있었으며, @Component 어노테이션을 통해 빈으로 등록해 놓은 상황이라 경험상으로 의존성 주입된 필드 값이 null인 것을 이해할 수 없었다. 해당 문제에 대해 여기저기 찾아보다가 원인을 찾고 해결하게 되었다. 🔎 원인 어이없게도 컨트롤러 매핑 메서드의 접근 지시자가 private인 것이 원인이었다. @PostMapping("/") @ResponseStatus(HttpStatus.OK) private ProductResponse.Register register(ProductDto prod.. 2024. 2. 17.
Spring Data Redis를 활용해서 레디스 기본 명령어 사용하는 방법 👀 소개 Spring Data Redis는 레디스와의 통합을 지원하여 개발자들이 레디스를 쉽게 사용할 수 있도록 도와준다. 해당 포스팅에서는 레디스의 기본 명령어 들을 Spring Data Redis를 활용하여 어떻게 구현하는지 알아보자. 의존성 추가 먼저, 프로젝트에 Spring Data Redis 의존성을 추가해야 한다. Maven을 사용한다면 pom.xml에 다음과 같이 의존성을 추가한다. org.springframework.boot spring-boot-starter-data-redis Gradle을 사용한다면, build.gradle 파일에 다음과 같이 추가한다. implementation 'org.springframework.boot:spring-boot-starter-data-redis' R.. 2024. 2. 12.
@Lob 사용시 DB와 엔티티 필드 타입이 다른 경우 발생하는 문제와 해결방법 😫 배경 진행 중인 프로젝트의 과거 코드 중 HTML 문서를 그대로 DB에 저장하는 내용이 있었다. HTML 문서 내용은 동적이고, 길이가 길었기 때문에 긴 문자열 저장을 위해 LOB을 사용했고, 별다른 문제없이 서비스를 이용해 왔었다. 그러다 어느 순간 서비스를 이용할 수 없는 문제가 발생했다. 이와 관련해서 파악한 원인과 해결 방법에 대해서 공유하고자 한다. 🔎 원인 문제 내용을 분석해 보니, 'DB에 선언된 LOB 타입'과 '엔티티에 사용된 @LOB 타입'이 다르게 사용되었기 때문에 발생한 문제였다. 서비스 DB에서는 BLOB 타입을 적용시켰는데, 막상 엔티티 필드에서는 String 타입으로 선언했기 때문에 CLOB 관련 로직이 적용되면서 데이터베이스에서 가져온 데이터를 처리할 수 없게 되어 문제가.. 2024. 1. 7.
JPA @Lob 이해하기 (with MariaDB) LOB 이란? - Large Object의 줄임말로서, 대형 객체 데이터를 저장하기 위한 가변 길이 데이터 유형이다. - BLOB, CLOB 2가지 종류가 있다. * BLOB(Binary Large Object) = 이미지, 오디오, 비디오 같은 이진 데이터를 저장한다. * CLOB = 대량의 텍스트 데이터를 저장한다. 어떻게 사용할까? 이미지, 오디오, 비디오 같은 데이터를 바이너리 형식으로 저장하거나, 대량의 텍스트 값을 저장할 때 사용하면 된다. 엔티티 객체 필드 위에 @Lob이라는 어노테이션을 달면 스프링이 추론하여 어떤 타입으로 저장할지 자동으로 판단한다. 따라서, (1) 데이터베이스에 정의한 컬럼 타입과 (2) 엔티티에 설정하는 타입을 반드시 일치시켜야 한다. (1) 데이터베이스 컬럼 타입 M.. 2024. 1. 6.