JPA

Web

[JPA] deleteAll() 과 deleteAllInBatch()

테스트 코드 관련 강의를 보다가 deleteAllInBatch() 에 대해서 알게 되었다. 해서 기존에 사용하고 있던 deleteAll() 과의 차이점을 정리해보려한다. deleteAll() 과 deleteAllInBatch() User 데이터를 10개 추가해두고 deleteAll() 과 deleteAllInBatch() 를 사용했을 때 각각을 비교해보자. ( UserRepository 는 JPARepository 를 상속받고 있다. ) deleteAll() deleteAll() 은 CrudRepository 내 정의 되어있는 기능으로 모든 엔티티를 삭제할 때 사용한다. 쿼리를 통해 확인한 내부 동작은 아래와 같다. 1. 작업을 수행하기 전 엔티티를 영속성 컨텍스트로 로드하기위해 select 쿼리를 실행..

Web

[JPA] @ColumnDefault 이해하기

엔티티의 특정 필드에 @ColumnDefault 를 이용하여 Default 값을 'N' 으로 설정하였는데 null 값으로 저장되는 이슈가 발생하였다. 해결방법에 대해 정리해보자. @ColumnDefault 동작 @ColumnDefault는 Hibernate 에서 제공하는 Annotation 으로, Entity 의 필드에 대해 데이터베이스 기본 값을 정할 때 사용한다. 예를 들어 isDeleted 라는 필드가 있고 기본 값을 'N' 으로 설정하고 싶을 땐 아래와 같이 설정하면 된다. @ColumnDefault("'N'") // default N private String isDeleted; 그런데 이렇게 설정하고 테스트를 해보면 기대했던 N 값이 아닌 null 값임을 확인할 수 있다. - Test Code..

Web

[Spring] Soft Delete with JPA

사이드 프로젝트 진행 중에 특정 데이터에 대해 Soft Delete 를 적용해달라는 요청을 받았었다. Soft Delete 란? 데이터를 영구적으로 삭제하지 않고 데이터가 삭제된 것처럼 처리하는 방법이다. 이렇게하면 데이터를 복구할 때 유용하며 Soft Delete 를 구현할 때는 데이터 항목에 isDeleted 등의 필드를 추가하여 삭제된 것처럼 처리한다. 예를 들어, Soft Delete 가 아닌 Hard Delete ( 물리적 삭제 ) 상태라면 user_id 가 1인 사용자를 삭제하는 경우 데이터베이스에서 해당 사용자의 레코드를 완전히 제거하게 된다. 반대로 Soft Delete 를 사용하였을 때는 아래의 is_deleted 필드가 'N' 에서 'Y' 로 바꿔 사용자가 삭제된 것처럼 처리하게 된다...

Web

[Spring] QueryDsl 로 동적 쿼리 짜기 with JPA

JPARepository 에서 제공하는 메서드로 해결이 안되는 경우 동적 쿼리를 짜야한다. 간단하게는 native query 로 해결할 수 있는데 개발자가 실수를 한 경우에 이는 컴파일 시점이 아닌 런타임 시점에서 고객이 그 메서드를 호출하는 행위를 한 경우에만 오류를 확인할 수 있게 된다. 이를 해결하기 위해 QueryDSL 을 적용해보자. QueryDSL 설정 1. spring boot 3.x QueryDSL 의존성 주입 ( Gradle 기준 ) // QueryDSL implementation "com.querydsl:querydsl-jpa:5.0.0:jakarta" annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta" annotationPro..

Web

[JPA] 양방향 순환 참조

JPA 양방향 관계를 설정하고 테스트하다가 Controller 단에서 아래 예외가 발생하였다. 찾아보니 JSON 직렬화 하는 과정에서 무한 참조로인해 생긴 예외로 원인과 해결방안에 대해 정리해보려한다. java.lang.IllegalStateException: Cannot call sendError() after the response has been committed .. java.lang.StackOverflowError: null .. ~[jackson-databind-2.15.3.jar:2.15.3] JPA 양방향 순환 참조 어떤 상황이었는지 간단하게 시나리오를 구현해보자. User 와 Notice 엔티티가 있고 1:N 양방향 관계이다. - User public class User { @Id @G..

Web

[JPA] 지연로딩과 즉시로딩

처음 웹 공부를 했을 때부터 JPA 를 썼기 때문에 그 쿼리를 주의깊게 보지 않았던 것 같다. 연관관계 매핑 시 fetchType 을 LAZY 로 하는 경우를 많이 봤을 것이다. 그 이유에 대해서 책을 통해 정리해보려 한다. JPA 의 FetchType ( LAZY 와 EAGER ) 연관관계 매핑 설정 시 FetchType 은 데이터베이스에서 데이터를 가져오는 전략을 지정하는 데 사용된다. 종류로는 LAZY 와 EAGER 두 가지가 있다. LAZY 는 지연로딩으로 해당 데이터를 필요할 때 가져오고, EAGER 는 즉시로딩으로 데이터를 즉시 가져온다. JPA 에서 @OneToMany 와 @ManyToMany 의 기본 FetchType 값은 LAZY 이고, @ManyToOne과 @OneToOne 은 EAGE..

Web

[JPA] 1:N 단방향 매핑과 N:1 양방향 매핑

프로젝트를 하다보면 자연스럽게 다대일 양방향 매핑을 사용하여 연관관계 매핑을 했을 것이다. 나는 일대다 단방향 매핑으로 설정을 하다가도 불편함을 느껴 다른 코드를 참조하여 다대일 양방향 매핑으로 변경했었는데 책을 통해 해당 내용을 정리해보려한다. 일대다 단방향 [1:N] 매핑과 단점 일대다 관계의 예로 팀과 회원을 볼 수 있다. 하나의 팀은 여러 회원을 참조할 수 있고 (일대다) 팀은 회원들을 참조하지만 반대로 회원은 팀을 참조하지않는다. (단방향) 이를 UML 로 보면 아래와 같은데 일대다 관계에서 외래키는 항상 다(MEMBER)쪽에 있음을 확인할 수 있다. 그러면, 이를 코드로 나타내보자. @Entity @Table @Getter @NoArgsConstructor(access = AccessLevel..

Web

[JPA] Dirty Checking 동작 방식 및 성능 개선

JPA 를 다시 공부하다가 변경감지를 내가 잘 이해하지 못했던 것 같아 정리해본다. Dirty Checking 동작 방식 JPA 의 영속성컨텍스트(Entitymanger)에는 1차 캐시와 쓰기 지연 SQL 저장소가 존재한다. 1차 캐시에는 id와 entity가 저장되고 쓰기 지연 저장소에는 쿼리가 쌓이는데 commit 하는 시점에 DB에 반영이 된다. 해서, 1차 캐시에 저장되어있는 엔티티를 수정하면 Dirty Checking(변경 감지) 으로 인해 쓰기 지연 저장소에 update 쿼리가 쌓이고 Transaction 이 끝나는 시점에 DB에 반영이 된다. 자바 코드로 commit이나 flush를 통해 커밋하는 게 아닌 테스트 시나리오 상에서 update 쿼리가 언제 호출되는지 보고싶어서 테스트 코드를 작..

limnj
'JPA' 태그의 글 목록