티스토리 뷰

문제 발생

먼저 정의된 Entity를 먼저 보겠다.

 

Member Entity

Team과 N:1 연관관계에 있다.

   
@Entity
@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@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
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@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

Member 양방향 연관관계 필드를 선언하였다.

@Entity
@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@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

Member를 조회할 때 Team과 join, fetch join을 사용하여 조회하고 있다.

public interface MemberSpringJpaRepository extends JpaRepository<Member, Long> {

    /**
     * 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();
}

 

Repository를 보면 join과 fetch join으로 조회하는 메서드가 존재한다. join과 달리 fetch join으로 조회하는 메서드를 호출하면 예외가 발생한다.

문제 원인

fetch join을 사용하고 new 연산자를 사용하여 dto로 변환할 수 없다. fetch join을 사용하는 이유는 Entity 상태에서 Entity Graph를 참조하기 위해서 사용하는 것이다. DTO는 Entity가 아니기 때문에 조회하는 것이 불가능하다. 

문제 해결

Entity로 반환하고 DTO로 변환하는 과정을 거친다.

// Entity -> DTO 변환
memberRepository.findMemberDtoWithJoin().stream()
        .map(member -> new MemberDto
            (member.getId(), member.getUsername(), member.getTeamName()));
Total
Today
Yesterday
최근에 올라온 글
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30