JPA18 JPA 두번 이상의 left join fetch가 필요할 때 해결 방법(MultipleBagFetchException 문제 해결) 프로젝트를 진행하면서 두개 이상의 OneToMany 리스트를 가진 객체에 대한 정보를 가져올 때 N+1 문제에 걸리지 않으면서 각각의 리스트들을 가져올 필요가 있었다. 만약 하나의 OneToMany 리스트만을 같이 다룬다면 left join fetch 를 적용하여 해결할 수 있다. 하지만 문제는 두 개의 리스트라는 점이다. left join fetch는 두 번 이상 사용할 수 없다.(OneToOne는 가능하다) 이는 잘못하면 카티젼 곱과 같은 형식으로 데이터가 전달될 위험이 있기 때문에 서버는 미리 MultipleBagFetchException 를 띄우며 에러처리를 한다. 그렇다면 이러한 상황에서 어떻게 해야할까? 이는 한번의 select – from where a=b절을 select – from whe.. 2021. 8. 23. JPA 특정 엔티티 삭제시 연관된 엔티티도 함께 삭제하기 프로젝트에서 하나의 엔티티를 삭제했을 때 이 엔티티와 연관된 다른 엔티티는 어떻게 될까?? 정답은 그 엔티티의 외래 키로 연결된 엔티티에서는 부모 엔티티가 없기 때문에 데이터베이스에서 외래 키 무결성 예외가 발생한다. 예를 들어 User 엔티티와 Article 엔티티가 있다고 보자. User와 Article는 일대다의 관계를 가진다. User 하나에 여러 개의 Article가 있는 셈이다. 여기서 만약 User를 삭제한다면 삭제한 User에 연결된 Article에서는 에러가 발생하는 것이다. 다시 말해 연관관계가 끊어졌다고 할 수 있다. 이러한 상황에서 User와 연관관계가 끊어진 Article를 고아 객체라고 한다. 그렇기에 부모 엔티티를 삭제할 때는 연관된 자식 엔티티를 모두 삭제한 후에 부모 엔티티.. 2021. 8. 15. JPA setter을 만들지 않아야 하는 이유 나는 JPA 엔티티를 만들면 항상 getter, setter을 만들었었다. 하지만 setter는 사용하지 않는 게 좋다고 한다. 이 글은 그 이유를 간단하게 기록해본 것이다. JPA에서 데이터 타입은 크게 값 타입과 엔티티 타입으로 나뉜다. 여기서 값 타입은 기본값 타입, 임베디드 타입, 컬렉션 값 타입 으로 나뉘고 기본값 타입은 자바 기본 타입(int, double), 래퍼 클래스(Integer), String 로 나뉜다. 엔티티를 구성할 때 값 타입으로 구성하는 경우가 많은데 각 값 타입은 다른 엔티티들과 공유를 하면 위험하다. 한 엔티티에서 다른 엔테티의 값을 변경하면 위험하기 때문이다. 일반적인 자바 기본 타입은 값을 대입하면 복제가 이뤄진다. 하지만 임베디드 타입같은 객체형식의 값타입은 값을 대.. 2021. 7. 22. JPA 임베디드 타입 JPA의 데이터 타입은 크게 값 타입과 엔티티 타입으로 나눈다. 값 타입은 기본값 타입, 임베디드 타입(복합 값 타입), 컬렉션 값 타입으로 나뉘고 엔티티 타입은 @Entity로 정의하는 객체이다. 기본 값 타입은 자바 기본 타입(ex. int, double), 래퍼 클래스(ex. Integer), String 로 구성된다. 먼저 임베디드 타입부터 설명하겠다. 임베디드 타입은 JPA에서 새로운 값 타입을 정의할 수 있도록 구현한 것이다. 즉 임베디드 타입도 int나 double와 같은 값 타입 이라는 것이다. 아래의 예시를 보자. @Entity @AllArgsConstructor @NoArgsConstructor @Getter @Builder public class Article { @Id @Genera.. 2021. 7. 22. JPA - 프록시와 연관관계(즉시로딩, 지연로딩, N + 1 문제) 들어가기 JPA는 데이터 베이스에 있는 객체를 가져올 때 우선 영속성 컨텍스트에 가져오게 된다. 그렇다면 그 객체와 연관된 객체를 가져올 때 어떻게 가져오는가?경우는 두 가지가 있다.첫 번째는 그 연관된 객체도 미리 영속성 컨텍스트에 올려놓는 것이다. 이 방식을 즉시 로딩이라 한다.두 번째는 그 연관된 객체를 사용하는 시점에 가져오는 것이다. 이 방식을 지연 로딩이라 한다.이 글에서는 이러한 두 가지 로딩 방식에 대해서 '프록시 객체'와 함께 설명할 것이다. 영속성 컨텍스트에 대한 내용이 많이 나오는데, 이에 대한 것은 https://khdscor.tistory.com/110를 참고하길 바란다. 본론 지연 로딩을 이용하기 위해선 실제 객체 대신에 데이터 베이스 조회를 지연할 수 있는 가짜 객체가 필요.. 2021. 7. 19. JPA 객체 매핑- 연관 관계 1. 겍체와 테이블의 연관관계 방식 객체 연관관계로 따지면 Member 객체는 Member.team 필드로 Team 객체와 참조(주소)로 단방향 연관관계를 맺으며 member는 team필드로 Team을 알 수 있지만 Team은 Member을 알 수 없다. 테이블로 따지면 양방향 연관관계이다(단반향이 없다). MEMBER 테이블의 TEAM_ID 외래 키를 통해 TEAM과 MEMBER은 서로 조인 할 수 있기 때문이다. 2. 연관 관계 매핑JPA를 사용해서 객체방식과 테이블 방식을 매핑한다. Member 객체에 아래처럼 작성한다. @ManyToOne @JoinColumn(name="TEAM_ID") private Team team; Member.team 과 MEMBER.TEAM_ID 를 매핑하는 것이 연관관.. 2021. 7. 8. JPA H2 데이터베이스 및 서버 실행시 자동 Insert 1. application.properties 에 아래 코드를 삽입한다. spring.h2.console.enabled=true spring.h2.console.path=/h2-console spring.datasource.url=jdbc:h2:mem:testdb spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password= spring.jpa.database-platform=org.hibernate.dialect.H2Dialect spring.jpa.hibernate.ddl-auto=create spring.jpa.properties.hibernate.format_sql=tru.. 2021. 6. 29. JPA 간략 정리해봄 객체지향언어인 자바에서는 객체를, 데이터를 다루는 관계형 데이터베이스에서는 테이블을 다룬다. 필요한 정보를 가져오고 싶을 때는 테이블 형태의 데이터를 객체의 형태로 집어넣어야 하고 정보를 집어넣을 때는 객체 형태의 데이터를 테이블 형태로 집어넣어야한다. 수정, 삭제 또한 객체와 테이블사이의 변환이 필요하다. (즉, CRUD기능) 예를 들면, 상속관계, 연관관계 등에서 객체와 관계형데이터베이스는 표현 방식이 다르기에 일일이 각 상황에 맞게 표현을 해주어야 한다. JDBC를 이용해서 직접 sql을 짤 때 하나의 함수를 짜는데도 많은 시간이 소요된다. 여러 함수를 짜려면 더 많은 시간이 소요될 것이다. 이를 위한 것이 ORM(ObjectRelationalMapping) 프레임워크이다. ORM 프레임워크는 객체.. 2021. 6. 29. JPQL 개념과 스프링 데이터 JPA 쿼리메서드 이용 JPA를 사용하여 프로젝트를 구현할 때 스프링 데이터 JPA를 이용하고 repository 인터페이스를 작성하여 CRUD기능을 사용하였을 것이다. 우리는 JPA를 사용하기 위해 Repository를 만들고 CRUD기능을 수행할 수 있다. 하지만 간단한 형식의 엔티티만을 가져올 뿐이지 특정 범위, 특정 경우, 특정 순서 등 복잡한 경우에 적용하기는 힘들다. 이러한 경우는 자세한 sql문을 이용해서 해결할 수 있다. ORM은 엔티티 객체를 대상으로 개발하므로 검색을 위한 sql문도 엔티티 객체를 대상으로 해야 하기에 JPQL을 사용한다. 스프링 데이터 JPA에서는 복잡한 쿼리를 쿼리 메서드를 이용하여 JPQL을 직접 짜는 것이다. 이 글에서는 JPQL에 대해서는 간단한 설명과 파라미터 바인딩에 대해서만 설명.. 2021. 6. 27. 이전 1 2 다음