inflearn logo
강의

Course

Instructor

Practical! Spring Data JPA

페치조인과 new 프로젝션

Resolved

311

Jin Heung An

3 asked

2

Member Entity

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Builder
@AllArgsConstructor
@ToString(of = {"id", "username", "age"})
@NamedQuery(
        name = "Member.findByAgeGreaterThanAndUsername",
        query = "select m from Member m where m.age > :age and m.username = :username"
)
public class Member {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "member_id")
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "team_id")
    private Team team;

    private String username;
    private int age;

    /**
     * 연관관계 편의 메서드
     */
    public void changeTeam(Team team) {
        this.team = team;
        team.getMembers().add(this);
    }
}

 

Team Entity

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Builder
@AllArgsConstructor
@ToString(of = {"id", "name"})
public class Team {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "team_id")
    private Long id;

    @OneToMany(mappedBy = "team", fetch = FetchType.LAZY)
    @Builder.Default
    private List<Member> members = new ArrayList<>();

    private String name;
}

 

MemberRepository

public interface MemberSpringJpaRepository extends JpaRepository<Member, Long> {

    List<Member> findByUsernameAndAgeGreaterThan(String username, int age);

    @Query(name = "Member.findByAgeGreaterThanAndUsername")
    List<Member> findByAgeGreaterThanAndUsername(@Param("age") int age,
                                                 @Param("username") String username);

    @Query(value = "select m from Member m")
    List<Member> findUsers();

    @Query(value = "select new study.datajpa.dto.MemberDto(m.id, m.username, t.name) from Member m join m.team t")
    List<MemberDto> findMemberDtoWithJoin();

    /**
     * fetch join -> new 프로젝션 예외 터짐
     */
//    @Query(value = "select new study.datajpa.dto.MemberDto(m.id, m.username, t.name) from Member m join fetch m.team t")
//    List<MemberDto> findMemberDtoWithFetchJoin();

    @Query(value = "select m from Member m join m.team t")
    List<Member> findMemberJoinWithTeam();
}

 

질문

    /**
     * join -> new 프로젝션 정상 수행
     */
    @Query(value = "select new study.datajpa.dto.MemberDto(m.id, m.username, t.name) from Member m join m.team t")
    List<MemberDto> findMemberDtoWithJoin();

    /**
     * fetch join -> new 프로젝션 예외 터짐
     */
//    @Query(value = "select new study.datajpa.dto.MemberDto(m.id, m.username, t.name) from Member m join fetch m.team t")
//    List<MemberDto> findMemberDtoWithFetchJoin();

@Query 애너테이션에서 쿼리문을 작성할 때, new 연산자를 사용하여 dto로 변환하여 반환하려고 합니다. Member-Team을 join 후 new 연산자를 사용하여 dto는 정상적으로 반환이 됩니다. 근데 페치조인을 사용 후 new 연산자를 사용하면 아래 예외가 터집니다.

fetch join으로는 new 연산자 사용이 안 되는 이유를 알고싶습니다.

 

발생하는 예외

java.lang.IllegalStateException: Failed to load ApplicationContext for [WebMergedContextConfiguration@3d1b6816 testClass = study.datajpa.repository.springjpa.MemberSpringJpaRepositoryTest, locations = [], classes = [study.datajpa.DataJpaApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceDescriptors = [], propertySourceProperties = ["org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizer@1255b1d1, org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@47da3952, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@28a0fd6c, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@5fb97279, org.springframework.boot.test.context.SpringBootTestAnnotation@3f26d230], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]

java spring spring-boot jpa

Answer 1

0

Jin Heung An

해결 완료했습니다.

https://www.inflearn.com/questions/23847/queryprojection%EA%B3%BC-fetch-join

existsByUserIdAndProjectId vs existsByUserAndProject 중 어떤 방식이 적절할까요?

0

65

1

existsByUserIdAndProjectId vs existsByUserAndProject 중 어떤 방식이 적절할까요?

0

101

3

MemberRepository 구현체

0

56

1

pdf 표현 질문드립니다.

0

60

1

로그가 남지 않는 문제.

0

79

1

테스트 라이브러리가 강의는 junit4가 맞나요??

0

68

2

pdf 파일과 차이점이 있는 것같은데 문제 없나요?

0

69

2

@PrePersist, @PreUpdate 호출 시점 질문드립니다.

0

90

2

Sort 인터페이스는 잘 사용 안하나요?

0

51

1

스캔대상 질문드립니다.

0

45

1

하이버네이트6에서의 최적화에 이은 질문

0

82

1

save() vs saveAndFlush DB 통신 횟수

0

51

1

순수 JPA 리포지토리 코드 수정부분

0

85

2

bulk연산 후 flush하는 이유를 모르겠어요

0

148

3

bulk insert 질문입니다.

0

174

2

교만했던 것 같아요.

0

143

1

RESTful 강의는 안하시는 건지 궁금합니다.

0

144

2

동적 테이블에 대한 질문

0

84

1

영속성 전이와 연관관계

0

129

2

강의 10:25 질문

0

72

1

단건 update 질문

0

94

2

엔티티 와 도메인의 경계

0

125

1

UsernameOnlyDto 타입 type mismatch 오류

0

115

1

Projection 개념과 데이터 전달과정에 대해 질문 있습니다.

0

131

1