사용자 도구

사이트 도구


java:jpa:springdatajpa

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

양쪽 이전 판 이전 판
다음 판
이전 판
java:jpa:springdatajpa [2019/06/04 14:20]
kwon37xi
java:jpa:springdatajpa [2024/02/07 14:43] (현재)
kwon37xi [Repository 구현]
줄 5: 줄 5:
   * [[java:jpa:springdatajpa:custom_repository|Spring Data JPA - Custom Repository]]   * [[java:jpa:springdatajpa:custom_repository|Spring Data JPA - Custom Repository]]
  
-====== 기본 Repository Interface ======+===== 기본 Repository Interface =====
 <code> <code>
 public interface MyEntityRepository extends JpaRepository<MyEntity, KeyClass>, MyEntityRepositoryCustom { public interface MyEntityRepository extends JpaRepository<MyEntity, KeyClass>, MyEntityRepositoryCustom {
줄 35: 줄 35:
 </code> </code>
  
 +===== 모든 Repository 에는 @Transactional 붙이기 =====
 +  * Spring Data JPA 뿐만 아니라 모든 Repository 에는 명시적으로 ''@Transactional''을 붙여야 한다.
 +  * 그렇지 않으면 Repository 에 추가된 메소드에는 트랜잭션이 걸리지 않는다.
 +  * 트랜잭션 없이 DB 작업이 수행되면 다양한 문제를 겪을 수 있다.
 +    * 특히 JDBC DataSource 에서 ''autocommit=false''가 기본으로 하고 작업시마다 ''autocommit=false|true'' 토글을 하지 않고 ''hibernate.connection.provider_disables_autocommit: true'' 인 경우에 문제가 된다.
 +    * Spring 은 JPA EntityManager 의 경우 DB 관련 작업이 시작되면 EM 을 생성하고 커밋/롤백시에 정리작업을 하는데, EM을 생성하는 것은 트랜잭션이 없어도 생성한다. 따라서 커밋/롤백이 없으면 정리가 안되어 EntityManager 가 계속 남아서 존재하는 현상이 발생하고 이는 일종의 leak 이며, DB쪽에서 커넥션을 끊을 경우 EM에서 오류가 발생하는 현상이 생긴다.
 +
 +<note warning>
 +모든 Repository 에는 ''@Transactional''을 붙여야한다.
 +</note>
 +
 +===== Repository 상속 금지 =====
 +  * 멀티 모듈 프로젝트에서 ''BoardRepository''가 도메인 모듈에 있을 때, API 모듈에서 이를 상속해서 ''BoardApiRepository'' 처럼 만들거나 하는 경우가 발견됨. **절대 상속하지 말 것**
 +  * 이 경우 도메인 모듈과 말단 모듈의 Repository가 둘다 Custom 구현을 필요로 할 경우 제대로 작동안하게 된다.
 +  * 또한, 메소드 이름 겹칠 때 뭘 선택하게 되는지 불확실한 등 문제가 많다.
 +  * 꼭 말단 모듈에서 Repository 메소드를 도메인모듈과 격리해서 구현하고자 한다면 **상속 없이 별개의 Repository로 따로 만든다.**
 +
 +===== Pageable 사용 금지 =====
 +  * [[https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/domain/Pageable.html|Pageable]]
 +  * [[https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/web/PageableDefault.html|@PageableDefault]]
 +  * [[https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/web/config/PageableHandlerMethodArgumentResolverCustomizer.html|PageableHandlerMethodArgumentResolverCustomizer]] : 기본 설정 override
 +  * Spring Data 에서 ''Pageable'' 을 인자로 받는 메소드는 기본적으로 **전체 갯수를 세는 쿼리를 추가로 요청**한다.
 +  * 이 기능은 데이터량이 적은 tutorial 프로젝트 수준에서나 쓸모 있다.
 +  * 대부분의 실무 서비스는 이런 방식의 페이징을 사용하면 시스템이 사용할 수 없을 정도로 큰 부하를 일으킨다.
 +  * 다른 문제 : page의 시작인 기본이 0인데 문제는 보편적인 서비스의 page 번호는 1로 시작한다. 이를 헷갈려 해서 호출자가 첫번째 페이지를 1로 호출하는 경우가 많다. 설정으로 해결 가능하나 이를 지키지 못하는 경우가 많이 발생한다.
 +  * [[database:seek_method|seek method]] 참조.
 +
 +===== Pageable 대신 Slice 사용 =====
 +  * [[https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/domain/Slice.html|Slice]] 는 ''Pageable'' 과 달리 전체 갯수를 세지 않는다.
 +  * 페이징이 필요하다면 되도록 전체 갯수는 한 번만 세고 ''Slice'' 를 이용해 페이지 데이터를 가져오게 한다.
 +  * 다만, ''Slice'' 도 ''offset/limit'' 방식으로 성능이 떨어지는 것은 동일하다.
 ===== Native Query ===== ===== Native Query =====
 <code java> <code java>
줄 158: 줄 189:
   * [[https://www.baeldung.com/spring-data-query-by-example|Spring Data JPA Query by Example | Baeldung]]   * [[https://www.baeldung.com/spring-data-query-by-example|Spring Data JPA Query by Example | Baeldung]]
   * [[https://www.baeldung.com/spring-data-jpa-repository-populators|Spring Data JPA Repository Populators | Baeldung]] : 실행시점 데이터 생성기   * [[https://www.baeldung.com/spring-data-jpa-repository-populators|Spring Data JPA Repository Populators | Baeldung]] : 실행시점 데이터 생성기
 +  * https://github.com/spring-projects/spring-data-examples
 +  * [[https://tecoble.techcourse.co.kr/post/2021-08-15-pageable/|Pageable을 이용한 Pagination을 처리하는 다양한 방법]]
 +  * [[https://www.baeldung.com/spring-rest-api-query-search-language-tutorial|Building a REST Query Language | Baeldung]]
java/jpa/springdatajpa.1559625643.txt.gz · 마지막으로 수정됨: 2019/06/04 14:20 저자 kwon37xi