관리 메뉴

제뉴어리의 모든것

순수 JPA로 Join시 유의 사항 본문

BugNote

순수 JPA로 Join시 유의 사항

제뉴어리맨 2021. 2. 11. 01:47

- 현재 상황

아래와 같이 Board 테이블과 Member 테이블이 존재한다.

 

Board
Member

그리고 Board의 writer_id는 Member의 id를 참조하고 있다 (Board.writer_id -> Member.id)

 

Entity적 상황 :

N : 1 상황인 두 엔티티 Board : Member 가 있으며 (한 멤버가 게시물을 여러개 쓸 수 있으므로)

Board는 Member를 참조하고 있으며 아래는 두 Entity 구조의 구조이다.

문제 상황 Board 엔티티

 

 

Member 엔티티

그리고 위에 두 엔티티를 JOIN하여 가져오는 소스는 아래와 같다.

        Object objects = entityManager.createQuery("select b, w from Board b left join b.writer_id w")
                .getResultList();

 

그런데 이 소스를 실행하면 아래와같은 sql이 생성되고 에러가 발생한다.

 

발생 쿼리 

2021-02-11 01:26:39.499  WARN 22700 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 1054, SQLState: 42S22
2021-02-11 01:26:39.499 ERROR 22700 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper   : (conn=2587) Unknown column 'board0_.writer_id_id' in 'field list'
2021-02-11 01:26:39.519 ERROR 22700 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not extract ResultSet] with root cause

 

에러내용은 board0_.writer_id_id 이란 필드를 찾을 수 없다는것이다..

생성한 jpql이나 정의한 엔티티의 변수명들을 봐도 board0_.writer_id_id 이란 필드는 존재하지 않는데 도대체 어디서 저런 필드가 나온건지..

다만 여러 테스트 결과로 추측컨데 참조를 당하는 엔티티(Member)의 PK가 참조하는 테이블(Board)의 참조 필드명에 붙어서 나온다는 것이다. Board.writer_id (참조 하는쪽) + Member.id (참조 당하는쪽)

그래서 여러 시도엔 결국 엔티티에 명시적으로 @JoinColumn(name="writer_id") 필드명을 적어주니 문제는 해결됬다. 

(참고로 다른 엔티티를 참조하는 참조필드의 테이블상의 필드명을 명시적으로 정의해주려면 @Column이 아니라 @JoinColumn을 사용해야한다)

해결 상황 Board 엔티티

 

그런데 어차피 writer_id라는 변수로 정의가 되어있는데.. 왜 또 @JoinColumn(name="writer_id") 이렇게 명시를 해줘야하는건지 파악이 되질 않는다..

그리고 다른 프로젝트에서는 @JoinColumn(name="writer_id") 을 쓰지 않아도 잘 됬어는데..

추후 자세히 알아봐야겠다

 

 

@ManyToOne 속성에는 @Column이 허용되지 않습니다. - Javaer101