본문 바로가기

전체 글145

[JPA] JPA 컬렉션 조회 성능 최적화 #2 - @BatchSize xxToMany 관계인 컬렉션을 조회할 때 성능을 최적화 및 N+1 문제를 해결하기 위해 fetch join을 사용한 경우 다음과 같은 두 가지 단점이 있습니다. 이 단점을 @BatchSize를 사용하면 한 번에 해결할 수 있습니다. 1. 컬렉션을 페치 조인하면 메모리에서 페이징을 시도합니다. 만약 데이터 수가 많은 경우 메모리 부족으로 인해 오류가 발생할 수 있습니다.2. 컬렉션 2개 이상 페치 조인하면 MultipleBagFetchException 예외가 발생 엔티티 코드더보기@Entity@Getter@Setterpublic class Order { @Id @GeneratedValue @Column(name = "order_id") private Long id; @ManyT.. 2024. 12. 14.
[JPA] JPA 성능 최적화 #1 - fetch join JPQL에서 fetch join을 사용하면 관련된 모든 속성이 select 절에 들어옵니다. 그리고 select 절에서는 fetch join을 사용한 엔티티의 속성을 직접 명시할 수 없습니다. 이로 인해 select 절에 많은 속성이 포함되면 성능 저하가 발생할 수 있습니다. 그렇다고 지연 로딩에서는 N+1 문제가 발생할 수 있기 때문에 fetch join을 사용해야 합니다. 그럼 fetch join을 사용하되 select 절에 원하는 속성만 사용하는 방법에 대해서 알아보겠습니다. 최적화 전return em.createQuery( "select o from Order o" + " join fetch o.member m" + " join fetch o.delivery d", Order.class) .ge.. 2024. 12. 10.
[JPA] 순환참조 문제해결 - 양방향 매핑 문제점 ≣ 목차순환참조 문제는 특정 조건에 만족할 때 발생합니다. 바로 양방향 관계인 경우 순환 참조 문제가 발생합니다.그럼 이제 순환 참조 문제가 무엇인지 알아보겠습니다. 순환참조란?순환참조는 두 개 이상의 객체가 서로를 참조하는 상황으로, 예를 들어 A 객체가 B 객체를 참조하고 B 객체가 다시 A 객체를 참조하는 경우에 해당합니다. 이러한 구조는 JPA 양방향 매핑과 유사하여 데이터베이스에서 객체를 직렬화할 때 문제가 발생할 수 있으며, 특히 JSON으로 변환할 때 무한 루프에 빠지거나 toString()을 사용할 때 무한 루프에 빠지게 됩니다.더보기toString() 무한 루프 예시@Entity@Tablepublic class Order { @ManyToOne(fetch = LAZY) @Joi.. 2024. 12. 9.
[JPA] Named 쿼리 Named 쿼리Named 쿼리는 사전에 정의해서 사용하는 정적 쿼리로, @NamedQuery 어노테이션이나 XML 파일에 정의하여 사용합니다. 이 쿼리는 로딩 시점에 초기화되며, 이후 재사용이 가능하고, 로딩 시점에 쿼리를 사전에 검사하여 오류를 미리 확인할 수 있습니다. 예를 들어, 이름을 제공받아 사용자 정보를 조회하는 쿼리를 정의할 수 있습니다.1. @NamedQuery@Entity@NamedQuery( name = "Member.findByUsername", query = "select m from Member m where m.username = :username")public class Member 2. XML 파일 select m from Memb.. 2024. 12. 3.
[JPA] 벌크(Bulk) 연산 벌크 연산JPA의 영속성 컨텍스트 특징 중 하나인 변경감지(Dirty Checking)에는  치명적인 단점이 있습니다. 예를 들어, 영속성 컨텍스트에 100개의 데이터가 있을 때, 이 100개 데이터의 변경사항이 모두 감지되면 JPA는 각 변경사항에 대해 자동으로 update 쿼리를 생성하여 적용합니다. 이 과정에서 각 변경 건마다 update 쿼리가 생성되기 때문에 성능 문제가 발생할 수 있습니다. 이를 해결하기 위해 JPA는 대량의 데이터를 한 번에 UPDATE 또는 DELETE할 수 있는 벌크 연산 기능을 제공합니다. 벌크 연산 사용 시 주의사항벌크 연산은 영속성 컨텍스트를 무시하고 데이터베이스에 직접 쿼리를 전달하는 방식이기 때문에 주의가 필요합니다. 벌크 연산을 실행한 후에 변경된 데이터를 가져.. 2024. 12. 2.
[JPA] JPQL 페치조인(fetch join)의 한계 및 해결방법 ≣ 목차fetch join의 한계1. fetch join 대상에는 별칭을 줄 수 없다??JPA에서 select t from Team t join fetch t.members m 쿼리에서 마지막 조인 대상인 t.members m에 별칭을 주면 안 되는데, 이는 JPA 표준에서는 지원하지 않기 때문입니다. 하이버네이트와 같은 몇몇 구현체는 별칭을 지원하지만, 이로 인해 데이터 무결성이 깨질 수 있는 문제가 발생할 수 있습니다. 김영한님의 책에서도 별칭을 잘못 사용하면 연관된 데이터 수가 달라져 데이터 무결성이 깨질 수 있다고 언급하고 있습니다. 하이버네이트를 기준으로 별칭만 줄 경우 일대다, 다대일 관계에서는 문제없이 실행되며, 아래 두 쿼리는 실행했을 때 에러가 발생하지 않습니다.String query1 .. 2024. 12. 2.
[JPA] JPQL 페치조인(fetch join) ≣ 목차페치조인(fetch join)Fetch Join은 JPQL에서 성능 최적화를 위해 제공되는 조인 방식으로, 연관된 엔티티나 컬렉션을 SQL 한 번의 쿼리로 조회할 수 있는 기능입니다. 이를 통해 N+1 문제를 방지하고 필요한 데이터를 효율적으로 가져올 수 있습니다. Fetch Join을 사용하면 쿼리에서 지정한 엔티티와 함께 연관된 엔티티를 즉시 로드할 수 있습니다. Fetch Join을 사용하면 지연 로딩(LAZY)으로 설정된 연관 엔티티를 특정 쿼리에서 즉시 로딩(EAGER)할 수 있어 필요한 경우에만 연관된 엔티티를 한 번의 쿼리로 가져올 수 있습니다. 이는 아래 쿼리문 JOIN FETCH 구문을 통해 구현됩니다.  select m from Member m INNER/LEFT/RIGHT jo.. 2024. 11. 28.
[JPA] JPQL 경로 표현식 ≣ 목차Member 엔티티@Entitypublic class Member { @Id @GeneratedValue private Long id; private String username; private int age; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "TEAM_ID") private Team team; @OneToMany(mappedBy = "member") private List order = new ArrayList(); @Embedded private Address address;} 경로 표현식 용어1. 상태 필드엔티티에 있는 값을 저장하기 위한 필드private Stri.. 2024. 11. 26.
[JPA] JPQL 함수 정리 - Hibernate 6.x 버전 사용자 정의 함수 등록 ≣ 목차연산자1. 비교 연산자=: 같음: 다름>: 큼>=: 크거나 같음2. 논리 연산자AND: 두 조건이 모두 참일 때OR: 두 조건 중 하나라도 참일 때NOT: 조건이 거짓일 때3. 기타 연산자LIKE: 문자열 패턴 매칭을 위해 사용BETWEEN: 특정 범위 내의 값을 찾기 위해 사용IN: 특정 값의 집합에 포함되는지를 확인 함수1. 숫자 관련 함수ABS(): 절대값CEIL(): 올림FLOOR(): 내림ROUND(): 반올림SQRT(x): x에 대한 제곱근을 반환MOD(n,m): n을 m으로 나눈 나머지를 반환2. 문자열 함수CONCAT(): 문자열 연결SUBSTRING(): 문자열의 일부 추출LENGTH(): 문자열 길이LOWER(): 소문자로 변환UPPER(): 대문자로 변환TRIM(): 앞 뒤 공.. 2024. 11. 26.
[JPA] JPQL 간단 정리 및 기본 문법 ≣ 목차  JPQL(Java Persistence Query Language) JPQL(Java Persistence Query Language)은 객체 지향 쿼리 언어로, SQL 쿼리과 달리 엔티티 객체를 대상으로 쿼리를 작성합니다. 즉 데이터베이스 테이블을 대상으로 쿼리 문을 작성하는게 엔티티(객체)를 대상으로 쿼리를 작성합니다. JPQL 특징쿼리를 작성할 때 엔티티와 속성 대소문자 구분합니다쿼리 키워드는 대소문자 구분하지 않습니다. (SELECT, FROM, WHERE, LIKE)from절에 테이블 이름이 아니라 엔티티 이름 사용별칭은 필수이나 as는 생략 가능SQL을 추상화해서 특정 데이터베이스 SQL에 의존하지 않습니다.JPQL 쿼리에서 엔티티를 입력하면, 해당 엔티티의 기본키로 인식됩니다. S.. 2024. 11. 25.