![](http://i1.daumcdn.net/thumb/C148x148.fwebp.q85/?fname=https://blog.kakaocdn.net/dn/v6vAB/btsJpmdNWkV/ezgUH08uD0YIcB6CqHKqI0/img.png)
왜 Entity Listener를 적용하였는가?지난 게시글에서 엔티티를 생성하거나 수정할 때 해당 엔티티의 인덱스를 생성 및 수정하는 작업을 위해 ApplicationEvent를 도입하여 서비스 간의 결합도를 줄이고, 트랜잭션 문제를 개선할 수 있었습니다. 그러나 지난 게시글에서 ApplicationEvent를 사용하는 방식에는 한 가지 단점이 있습니다. 매번 엔티티를 생성하거나 수정할 때마다 applicationEventPublisher.publishEvent() 메서드를 호출하는 코드를 작성해야 한다는 점입니다. 아래의 코드처럼 모든 이를 위해 모든 비즈니스 로직에서 일일이 이벤트 발행 코드를 추가해야 합니다.class UserService( private val userIndexService:..
![](http://i1.daumcdn.net/thumb/C148x148.fwebp.q85/?fname=https://blog.kakaocdn.net/dn/bENCcS/btsJnvo6Bwa/p8GRdPK2xAa4NunSIPtVk1/img.png)
왜 Application Event 를 도입하기로 하였는가.ElasticSearch를 사용하여 검색 기능을 구현하면서, 엔티티를 생성하거나 수정할 때 해당 엔티티의 인덱스를 생성 및 수정하는 작업도 함께 수행해야 했습니다. 기존 코드에서는 User 객체를 생성할 때 UserService에서 UserIndexService를 의존성 주입받아 사용하며, User 객체 생성 후 인덱스를 생성하는 방식으로 구현되었습니다.class UserService( private val userIndexService: UserIndexService) { @Transactional fun create(name: String, identity: Identity) : User { val user = U..
![](http://i1.daumcdn.net/thumb/C148x148.fwebp.q85/?fname=https://blog.kakaocdn.net/dn/dihXjS/btsJiIAUytR/E1CakgnWoRkstSUo2BE7s1/img.png)
특정 엔티티의 총 개수 를 조회하기 위해서 QueryDSL 의 fetchCount() 메서드를 사용했습니다.하지만, fetchCount() 메서드가 회색 처리되고, 취소선이 나타나는 것을 발견했습니다. Warning 메세지에는 'fetchCount(): Long' is deprecated. 라는 내용이 뜨는데, 그 이유와 해결 방법에 대해 알아보겠습니다. fetchCount(), fetchResulsts() 의 Deprecation저희 팀이 사용하는 QueryDSL 5.0.0 버전부터는 fetchCount() 가 deprecated 되었습니다. 이 메서드가 더 이상 권장되지 않는 이유는 공식 문서에서 다음과 같이 설명하고 있습니다. fetchCount() 는 쿼리 결과의 개수를 계산하기 위해서 count..
![](http://i1.daumcdn.net/thumb/C148x148.fwebp.q85/?fname=https://blog.kakaocdn.net/dn/LmFNq/btsJcPNCYym/AtvvfGIKI6ooGD7SOnIB7K/img.png)
엔티티를 저장한 후, 그 정보를 이메일로 보내는 기능을 구현하였습니다. 이메일을 전송하는 작업은 시간이 오래 걸리는 작업이므로, 이를 비동기적으로 처리하기 위해 메세지 큐를 사용하였습니다. 저희 팀은 AWS 의 SQS(Simple Queue Service) 를 사용하고 있습니다. 간단하게 예시를 들어보겠습니다. 우선 메세지 전송 처리부터 구현해보겠습니다.@Transactionalfun create(seller: Seller, inquiry: Inquiry): InquiryHistory { val inquiryHistory = inquiryRepository.save(InquiryHistory( inquiry = inquiry, actionAt = ZoneDateTime.n..
![](http://i1.daumcdn.net/thumb/C148x148.fwebp.q85/?fname=https://blog.kakaocdn.net/dn/bQ53qo/btsI5kAmIms/Gifj3KDFS3yE7dHBKkNpo0/img.png)
문제Seller 와 1:N 관계를 가지고 있는 SellerUsers 의 첫번째 요소를 가지고 오기 위해서 List 클래스의 first() 메소드를 호출하였을 때 예외가 발생하였습니다. 이와 관련하여 간단하게 코드로 구현하였습니다.class Class1Service( private val sellerService: SellerService private val class2Service: Class2Service) { fun call()(sellerId) { val seller = sellerService.findSeller(sellerId) class2Service.call(seller) }}Class1Service.call() 메소드에서 sellerId 를 ..
![](http://i1.daumcdn.net/thumb/C148x148.fwebp.q85/?fname=https://blog.kakaocdn.net/dn/cJWpRl/btsJqeHRWtp/h8l5UPsK0tnHbklCkIteb1/img.png)
엔티티의 생명주기는 영속성 컨텍스트와의 관계를 통해 이해할 수 있습니다. 엔티티가 영속성 컨텍스트 내에서 어떤 상태에 있는지에 따라, 그 생명주기는 크게 네 가지로 구분됩니다 : 비영속(New), 영속(Managed), 준영속(Detached), 삭제(Removed) 입니다. 1. 비영속 상태(New)엔티티가 아직 영속성 컨텍스트에 저장되지 않은 상태로, 데이터베이스와는 전혀 연관이 없습니다. 예를 들어, 'new' 키워드로 새롭게 생성된 객체는 비영속 상태입니다.Member member = new Member();member.setId(1L);member.setName("1번 사용자"); 2. 영속 상태 (Managed)엔티티가 영속성 컨텍스트에 의해 관리되는 상태입니다. 이 상태에서 엔티티는 데이터베..
![](http://i1.daumcdn.net/thumb/C148x148.fwebp.q85/?fname=https://blog.kakaocdn.net/dn/yRSyj/btsJrsLTwmZ/KZH4JpumsC6SpQhw2ydVx1/img.png)
영속성 컨텍스트(Persistence Context)이란?영속성 컨텍스트는 애플리케이션과 데이터베이스 사이에 위치해 엔티티를 영구 저장(영속)하는 가상의 데이터베이스입니다. 이는 논리적인 개념으로, JPA에서 엔티티의 생명주기를 관리하고, 데이터베이스와의 상호작용을 최적화하는 역할을 합니다. 이번 글에서는 영속성 컨텍스트에 어떻게 접근하는지, 영속성 컨텍스트의 구성요소는 무엇인지, 그리고 영속성 컨텍스트가 어떤 일을 하는지 알아보겠습니다. 영속성 컨텍스트 접근하에 접근하는 도구 EntityManager 와 그를 생성하는 EntityManagerFactoryEntityManager 는 영속성 컨텍스트에 접근할 수 있는 주요 인터페이스입니다. 예를 들어, entityManager 는 persist 메서드를..
트랜잭션이란? 데이터베이스의 상태를 변화시키기 위해서 수행하는 작업의 단위이다. 데이터베이스 상태를 변화시키는 것은 질의어(SELECT, INSERT, DELETE, UPDATE)로 데이터베이스에 접근하는 것을 말한다. 이때, 작업의 단위는 질의어 한 문장이 아니다. 예를 들어, 상품을 구매하면 포인트를 적립하는 비즈니스 로직이 구현되기 위해서는 1. 상품을 구매한 구매내역을 데이터베이스에 등록하고 2. 그 상품을 구매한 사용자의 포인트 점수를 갱신해주어야 한다. 여기서 작업단위는 구매내역을 등록하는 INSERT문과 사용자의 포인트 점수를 갱신하는 UPDATE문을 합친 것이다. 이러한 작업단위를 하나의 트랜잭션이라고 한다. 쉽게 말해 데이터베이스에 하는 여러 개의 작업들이 마치 하나의 그룹처럼 묶여서 처..
![](http://i1.daumcdn.net/thumb/C148x148.fwebp.q85/?fname=https://blog.kakaocdn.net/dn/lwz46/btsJp8tvMjO/eut6V0EQXFKO3RxRalKTM0/img.png)
Spring 의 생명주기를 알고자 한다면,,,Spring의 생명주기는 스프링 컨테이너와 그 안에서 관리되고 있는 스프링 빈의 생명주기에 따릅니다. 스프링 컨테이너는 애플리케이션의 설정 정보를 바탕으로 애플리케이션에서 사용할 객체(빈)를 생성하고 관리합니다. 이 과정에서 스프링 컨테이너와 빈 객체는 각자의 생명주기를 가지며, 이 새명주기는 서로 밀접하게 연결되어 있습니다. 스프링 컨테이너의 생명주기스프링 컨테이너의 생명주기는 크게 세 단계로 나눌 수 있습니다: 1. 컨테이너 초기화: 스프링 컨테이너를 생성하고 설정 파일 또는 클래스에서 정의된 빈들을 초기화합니다.2. 컨테이너 사용: 애플리케이션이 실행되는 동안, 컨테이너는 빈을 제공하고, 빈은 필요한 작업을 수행합니다.3. 컨테이너 종료: 애플리케이션이 ..
![](http://i1.daumcdn.net/thumb/C148x148.fwebp.q85/?fname=https://blog.kakaocdn.net/dn/cKOpYN/btsyTrijiZe/e7kpzG3Y19nxCEXAiLy4Q0/img.png)
스프링 컨테이너란? 1. 자바 객체의 생명주기를 관리하고 2. 생성된 자바 객체에게 부가 기능을 제공한다. 스프링에서는 자바 객체를 '빈(Bean)'이라고 부른다. 즉, 스프링 컨테이너는 스프링 빈의 생명주기를 관리하고, 생성된 스프링 빈에게 부가 기능을 제공한다. 스프링 컨테이너는 ApplicationContext라고도 부른다. 좀 더 상세하게는 스프링 컨테이너는 ApplicationContext가 상속하고 있는 인터페이스 'BeanFactory'와 구분해서 사용하지만, BeanFactory를 직접 사용하는 경우는 거의 없어 일반적으로 ApplicationContext를 스프링 컨테이너라고 한다. BeanFactory는 스프링 컨테이너의 최상위 인터페이스다. 1. BeanFactory는 빈의 생성과 관..
- Total
- Today
- Yesterday
- 영속 상태
- 영속성 컨텍스트
- entitylisteners
- CI와 CD의 차이
- java
- Hibernate
- Spring Boot
- IAM
- LeetCode
- appliationeventlistener
- Route53
- acm
- Spring
- 프로그래머스
- network
- CI/CD
- aws
- EC2
- springboot
- DevOps
- CodeDeploy
- 정렬
- persistencecontext
- 트랜잭션
- JPA
- 자바
- githubactions
- 지연 대기열
- fetchcount()
- 네트워크
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |