해결된 질문
24.02.05 23:55 작성
·
217
·
수정됨
2
@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);
}
}
@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;
}
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]