HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
🤩
개발
/
Spring Data
Spring Data
/
🧣
JPA(Java Persistence API)
/
📀
JPA 기본요소
📀

JPA 기본요소

Repository InterfaceRepositorygetOne() ↔ findById() 의 차이deleteAll() ↔ deleteAllInBatch()Like 검색 (ExampleMatcher) → queryDSL를 결국 쓰게됨Exception TranslationConsistent Exception Hierarchy

Repository Interface

Repository

  • JpaRepository를 이용하여 이렇게 쓸수있도록 한게 Spring data jpa
  • 첫번째 Generic은 @Entity로 선언된 클래스. 두 번째 generic은 @Id의 타입
  • JpaRepository가 구현하는 CrudRepository 여기에 사용하는 많은 기능들이 포함되어 있음. 이걸 가지고 extend 해서 이용하기도 함
  • JpaRepositry를 구현한 UserRepository가 interface인데도 코드가 동작하는 이유 : AOP
    • MethodInterceptor라는 AOP 인터페이스를 통해 JpaRepository 메서드 콜을 가로채 가서 메서드 이름 기반으로 쿼리를 작성하게 됨

getOne() ↔ findById() 의 차이

deleteAll() ↔ deleteAllInBatch()

  • delete는 실행 전에 해당하는 id가 존재하는지 select를 함
  • deleteAll() 은 해당하는 id들 존재하는지 하나씩 체크, 하나 delete 이걸 반복함

Like 검색 (ExampleMatcher) → queryDSL를 결국 쓰게됨

  • withIgnorePaths 는 해당 property는 무시하고, withMacher는 email property에서 해당하는 값으로 끝나는지를 체크하도록 구성한 것임
  • withIgnorePaths가 없으면 “ma”라는 name을 가지는 User를 찾게 됨(ExactMatch)
  • matcher 넣지 않으면 exactmach로 적용됨
 

Exception Translation

[ Spring Docs ] DAO Support

Consistent Exception Hierarchy

  • Spring은 기술에 specific하게 다른 exception (eg. SQLException) 들을 Spring 만의 exception class hierarchy(root : DataAccessException) 안에서 translation 해서 exception을 던지게 해줌
 
public interface UserRepository extedns JpaRepository<User, Long>{ }
//getOne() -> lazy fetch @Test @Transactional // 이걸 안붙여주면 아래 에러가 나게 됨. session 이 없다는 에러. // could not initialize proxy [com.example.bookmanager.domain.User#3] - no Session // 붙여 주어야 session 유지가 됨 void crud(){ User user = userRepository.getOne(3L); System.out.println(user); } //getOne() 구현 부분. em.getReference()를 통해 참조값을 가져오고 실제 값이 필요할때 세션을 통해 조회 @Override public T getOne(ID id) { Assert.notNull(id, ID_MUST_NOT_BE_NULL); return em.getReference(getDomainClass(), id); } //findById 는 eager fetch @Test void crud(){ User user = userRepository.findById(3L).orElse(null); System.out.println(user); } //findByID() 구현 -> em.find() @Override public Optional<T> findById(ID id) { Assert.notNull(id, ID_MUST_NOT_BE_NULL); Class<T> domainType = getDomainClass(); if (metadata == null) { return Optional.ofNullable(em.find(domainType, id)); } LockModeType type = metadata.getLockModeType(); Map<String, Object> hints = new HashMap<>(); getQueryHints().withFetchGraphs(em).forEach(hints::put); return Optional.ofNullable(type == null ? em.find(domainType, id, hints) : em.find(domainType, id, type, hints)); }
@Test void crud(){ ExampleMatcher matcher = ExampleMatcher.matching() .withIgnorePaths("name") .withMatcher("email", endsWith()); Example<User> example = Example.of(new User("ma", "fastcampus.com"), matcher); userRepository.findAll(example).forEach(System.out::println); } // 생성된 쿼리 select user0_.id as id1_0_, user0_.created_at as created_2_0_, user0_.email as email3_0_, user0_.name as name4_0_, user0_.updated_at as updated_5_0_ from user user0_ where user0_.email like ? escape ?