Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.lang.IllegalStateException: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection] with root cause org.h2.jdbc.JdbcSQLInvalidAuthorizationSpecException: Wrong user name or password
sol ) h2 user name 과 password 를 지정해준다. ( user name 만 등록해둬 된다곤 하는데,,,) 공백 주의 !
spring.jpa.hibernate.ddl-auto=none : JPA는 테이블을 자동으로 자동으로 생성하는 기능을 제공하는데 none를 사용하면 해당 기능을 끈다. create를 사용하면 엔티티 정보를 바탕으로 테이블도 직접 생성해준다.
JPA 엔티티 매핑
@Entity, @Id @GenerateValue(strategy = GenerationType.IDENTITY), @Column 등
JPAMemberRepository 작성. JPQL 언어 사용
서비스 계층 MemberService에 트랜잭션 추가 @Transactional
스프링은 해당 클래스의 메서드를 실행할 때 트랜잭션을 시작하고, 메서드가 정상 종료되면 트랜잭션을 커밋한다. 만약 런타임 예외가 발생하면 롤백한다.
@Transactional
: JPA를 통한 모든 데이터 변경은 트랜잭션 안에서 실행해야 한다.
스프링 데이터 JPA
스프링 부트와 JPA 기반 위에, 스프링 데이터 JPA라는 프레임워크를 더한다.
핵심 비즈니스 로직을 개발하는데 집중할 수 있다.
실무에서 관계형 데이터베이스를 사용한다면 스프링 데이터 JPA는 필수 이다.
스프링 데이터 JPA는 JPA를 편리하게 해주는 기술이다. 따라서 JPA를 먼저 학습한 후에 스프링 데이터 JPA를 학습해야 한다.
에러
SpringConfig 수정 시 아래와 같은 빈 중복 등록 문제 에러가 발견되었다.
Could not autowire. There is more than one bean of 'MemberRepository' type
sol ) 현재 SpringDataJpaMemberRepository 를 작성하기 위함이기에, 이전에 사용했던 JdbcTemplateMemberRepository 또는 MemoryMemberRepositoy 등에 @Repository 어노테이션이 등록 되어 있다면 지워 해결.
SpringConfig에서 스프링 컨테이너에서 MemberRepository를 주입하는 것을 알수있다.
MemberRepository는 등록한게 없는데 ?
보면 public interface SpringDataJpaMemberRepository 인터페이스를 만들고 extends JpaRepository<Member,Long>, MemberRepository
스프링이 인터페이스에 대한 구현체를 만들어 내고, 스프링 빈에 등록한다. 그래서 인젝션을 받을 수 있다.
스프링 데이터 JPA 제공 기능
-인터페이스를 통한 CRUD
- 'findByName()' , 'findByEmail()' 처럼 메서드 이름 만으로 조회 기능 제공
- 페이징 기능 자동 제공
참고 : 실무에서는 JPA와 스프링 데이터 JPA를 기본으로 사용하고, 복잡한 동적 쿼리는 Querydsl이라는 라이브러리를 사용하면 된다. Querydsl을 사용하면 쿼리도 자바 코드로 안전하게 작성할 수 있고, 동적 쿼리도 편리하게 작성할 수 있다. 이 조합으로 해결하기 어려운 쿼리는 JPA가 제공하는 네이티브 쿼리를 사용하거나, 앞서 학습한 스프링 jdbcTemplate를 사용하면 된다.