일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
- es6
- 파이썬
- TypeScript
- VUE
- BFS
- AWS
- JavaScript
- kubernetes
- 백엔드
- 백준
- HTML
- 웹
- k8s
- 가상화
- 이슈
- 쿠버네티스
- 컴퓨터공학
- 프론트엔드
- 블록체인
- 알고리즘
- CSS
- react
- 솔리디티
- next.js
- docker
- 타입스크립트
- 클라우드
- 자바스크립트
- 리액트
- 이더리움
- Today
- Total
즐겁게, 코드
JPA 이슈 디버깅 기록, JpaRepository는 무엇인가 본문
1. 디펜던시 오류 디버깅
TL;DR : JPA가 jakarta.persistence와 javax.persistence 두 버전으로 분화되어 있다.
둘을 혼용하지 않고 jakarta.persistence로 통일해 문제를 해결할 수 있었다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
이놈이 없으면 에러는 발생하지 않으나, H2 DB에 접근하지 못하는 문제가 있다.
하지만 위 의존성을 추가하면 H2 Console이 제대로 잡히기는 하나,
Class org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider does not implement the requested interface jakarta.persistence.spi.PersistenceProvider
라는 익셉션이 발생한다.
무엇이 문제인가 의심했는데, 이를 해결한 과정은 다음과 같다.
2. Jakarta Persistence와 Javax Persistence
내가 작성한 엔티티는 이런 형태였다.
package com.example.entity;
import javax.persistence.Entity; // <---- javax.persistence
import javax.persistence.Id; // <---- javax.persistence
@Entity
public class TodoEntity {
@Id
private Long id;
}
그런데 에러로그 중 'does not implement the requested interface jakarta.persistence.spi.PersistenceProvider'
라는 단락의 'jakarta.persistence' 라는 녀석이 'javax.persistence' 와 '유사하나 다른' 도구임을 찾을 수 있었다. (+ 조금 더 자세한 글)
그래서 'javax.persistence' 와 'jakarta.persistence' 가 공존하면 안될 것 같아 'javax.persistence' 를 걷어내야 할 것 같았고, 찾아본 결과 내가 hibernate-entitymanager
라는 디펜던시를 pom.xml에 추가한 것을 알 수 있었다.
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.6.15.Final</version>
</dependency>
(아마 GPT가 알려준 것을 그대로 믿은게 화근인 듯 하다 🥲)
hibernate-entitymanager
를 pom.xml에서 제거하고, 엔티티를 정의할 때 사용했던 javax.persistence.Entity 및 Id를 jakarta.persistence로 교체하니 에러 없이 제대로 실행되는 것을 확인할 수 있었다.
추가로 Hibernate는 내가 pom.xml에 따로 정의할 필요 없이 spring-boot-starter-data-jpa
패키지에 포함되어 제공된다고 하니, hibernate-entitymanager
를 직접 추가하지 않도록 하자.
3. @RestController와 @Controller
- @Controller는 어노테이션을 붙인 클래스가 Spring에서 사용하는 컨트롤러임을 표시한다.
- @RestController는 @Controller에 @ResponseBody 어노테이션을 추가한 축약형 어노테이션이다.
- @ResponseBody는 메서드가 리턴하는 값이 서버의 응답 본문에 포함됨을 표시한다.
- 요약
@Controller는 서버가 뷰를 생성하는 전통적인 웹 어플리케이션에 주로 사용된다.
JSON 또는 XML 등으로 RESTful한 웹 서비스를 구현할 때는 @RestController 어노테이션을 주로 사용한다.
4. JpaRepository
이제 H2 데이터베이스와 연결은 잘 마쳤으니, CRUD를 해보자.
그런데 CRUD도 내가 직접 정의할 필요 없이, Lombok처럼 자동으로 완성해주는 도구가 있다고 한다.
바로 JpaRepository 인데, 이를 위해 엔티티와 레포지토리 클래스를 준비해 보자.
// entity/TodoEntity.java
package com.example.entity;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
@Entity
public class TodoEntity {
@Id
private Long id;
private String title;
private Boolean isCompleted;
}
// repository/TodoRepository.java
package com.example.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.example.entity.TodoEntity;
// class가 아니라 interface로 정의해야 함에 유의하자!
// class로 정의하면 JpaRepository가 suggest 되지 않는다.
public interface TodoRepository extends JpaRepository<TodoEntity, Long> {
}
JpaRepository를 상속받으면 제네릭의 인자로 전달받은 엔티티 를 다룰 수 있는 메서드들을 만들어준다.
JpaRepository가 생성하는 메서드들
'🧺 일상다반사 > TIL' 카테고리의 다른 글
12월 9일 : MySQL 접속 오류, DTO와 엔티티, 자바의 List 인터페이스 (3) | 2023.12.09 |
---|---|
12월 4일 TIL : mySQL 의존성 오류, DTO, Lombok (0) | 2023.12.04 |
12월 3일 TIL : 스프링 기초, 라우트, Automatic Batching (2) | 2023.12.03 |