본문 바로가기
[JAVA]/JPA

JPARepository의 findAll() 호출 시 하나의 Row가 중복해서 여러 개 들어가는 경우와 특정 컬럼만 null이 들어가 있는 경우 (엔티티명과 컬럼명의 올바른 매핑 방법)

by 황원용 2023. 5. 19.
728x90
💡 JPARepository의 findAll() 메서드를 호출해서 List에 저장을 했는데 하나의 Row 값만 잔뜩 들어가 있었다. DB를 확인해 보니 맨 위 첫 번째 row 데이터였는데 테이블의 row 수만큼 데이터가 들어가 있었기 때문에 매핑에 문제가 있음을 단번에 알아챘다. 



테스트를 진행해 보자.

  • 우선 로컬 DB에 테이블을 생성한다.

 

 

  • 칼럼명을 짓고 더미 데이터도 적당하게 넣는다.

 

 

  • test 데이터베이스의 test 테이블에 10개의 row가 들어가 있다.

 

 

  • 엔티티를 생성한다.
  • 나는 두 가지를 테스트할 예정이므로 일부러 id와 name 필드명 테이블의 칼럼명과 다르게 했다.
  • seq는 test 테이블의 ID에 해당한다.
  • name은 test 테이블의 USER_NAME에 해당한다.
  • 나머지 칼럼명은 필드명과 일치한다.

 

 

  • JPARepository를 상속받는 TestRepository 생성

 

 

첫 번째 테스트

  • 테스트 케이스를 작성했다. testrepository의 findAll() 메서드를 호출하고 로그를 찍는 테스트이다. 돌려보자.

 

 

  • 띠용.. 왼쪽은 testEntity의 seq(테이블의 ID)이며 오른쪽은 testEntity의 name(테이블의 USER_NAME)이다.
  • 하나는 중복값이 나오고 다른 하나는 값이 들어가 있지 않다.

 

 

  • Java에서는 참조를 사용하여 객체를 직접 출력할 때 객체의 toString() 메서드를 호출한다.
  • toString() 메서드는 기본적으로 객체의 문자열 표현을 <ClassName>@<HashCode> 형식으로 반환한다.
  • 해시 코드(Hash Code)는 일반적으로 JVM(Java Virtual Machine)의 현재 실행 중인 개체에 대한 고유 식별자이다.
  • 따라서 위 10개의 객체는 전부 같은 객체가 반복해서 리스트에 들어갔음을 보여준다.

 

  •  똑같은 객체가 들어가 있다. 이는 엔티티의 필드명과 테이블의 칼럼명이 달라 JPA가 엔티티와 테이블을 매핑할 때  개별 개체에 대해 올바른 매핑이 불가능해 결과적으로 동일한 개체 인스턴스를 반복하여 반환하게 된 것이다. 이를 해결하기 위해서는 @Id에 해당하는 필드명을 테이블의 칼럼명과 같게 하여 자동 매핑이 가능하도록 바꾸거나, @Column(name = "") 애너테이션을 이용해 수동 매핑을 해주면 된다.

 

 

  • 나는 @Column 애너테이션을 이용해 수동 매핑해 주었다.

 

 

  •  테이블의 값이 중복되지 않고 정상적으로 들어온 것을 확인할 수 있다.

 

 

두 번째 테스트

  • 같은 문제였던 필드명인 name에 대해 데이터베이스 테이블 명인 USER_NAME을 수동 매핑해 주었다.

 

 

  • 필드명과 칼럼명이 모두 정상적으로 매핑된 모습을 확인할 수 있다.

 

 

정리

  • JPA는 기본적으로 카멜케이스의 엔티티 필드명을 스네이크케이스의 데이터베이스 테이블 칼럼명으로 자동매핑해 준다.
  • 만약 자동 매핑이 불가능한 경우(엔티티 필드명과 테이블 칼럼명이 다른 경우) @Column을 사용해 수동 매핑해줘야 한다.
  • @Id에 해당하는 기본키는 반드시 매핑이 되어야 정상적으로 테이블 row 값을 모두 불러올 수 있다.
728x90