부가적으로 varchar 사이즈 255 를 넘을 경우 @ColumnDefinition 이나 @Lob 을 사용한다.
직접 함수를 작성하여 리포지토리를 구성하고 싶다.
- 스프링에서 DAO 를 만드는 것과 같다.
- 인터페이스에 필요한 메서드를 정의
- 구현클래스(접미어는 반드시 Impl) 생성 및 @Repository, @Transactional 선언
- EntityManager 등을 이용한 메서드 작성
만약 구현클래스에 Impl 이라는 접미사 외에 다른 접미사를 채택하고 싶다면 @EnableRepositories 의 repositoryImplementationPostfix 속성에 원하는 접미사를 제시하면 된다.
재정의
- CustomRepository 인터페이스에 기존 메서드 시그니처를 동일하게 선언하면, JPA 는 사용자가 작성한 메서드를 우선시 하게 되어 재정의가 가능하다.
1. 원하는 메서드를 제시한 인터페이스
public interface PostCustomRepository<T> {
List<Post> findMyPost();
void delete(T entity); // 재정의를 위해 선언
}
2. 인터페이스 다중 상속 방법을 이용해 JpaRepository 상속 인터페이스에 추가로 상속한다.
public interface PostRepository extends JpaRepository<Post, Long>, PostCustomRepository<Post> {
}
3. @EnableRepositories 의 repositoryImplementationPostfix 속성에 제시한 접미사를 쓰는 구현클래스
@Repository
@Transactional
public class PostCustomRepositoryImpl implements PostCustomRepository<Post> {
@Autowired
EntityManager entityManager;
@Override
public List<Post> findMyPost() {
System.out.println("Custom findMyPost");
return entityManager.createQuery("SELECT P FROM Post AS P ", Post.class).getResultList();
}
@Override
public void delete(Post post) {
System.out.println("Custom Delete");
entityManager.remove(post);
}
}
JPA 에서 제공하는 기능인 Dirty Checking + Write Behind 기능으로 인해 insert 및 delete 쿼리는 작동하지 않는다.
@RunWith(SpringRunner.class)
@DataJpaTest
public class PostRepositoryTest {
@Autowired
private PostRepository postRepository;
@Test
public void crud(){
Post post = new Post();
post.setTitle("Hibernate");
postRepository.save(post);
postRepository.delete(post);
}
}
Hibernate:
call next value for hibernate_sequence
Custom Delete
select 메서드를 insert 밑으로 내리면 Dirty Checking + Write Behind 에 의해 Rollback 될 데이터로 간주(@DataJpaTest 의 @Transactional)하여 delete 작업은 진행되지 않으며 select 를 위해 insert 작업만 작동한다.
@RunWith(SpringRunner.class)
@DataJpaTest
public class PostRepositoryTest {
@Autowired
private PostRepository postRepository;
@Test
public void crud(){
Post post = new Post();
post.setTitle("Hibernate");
postRepository.save(post);
postRepository.findMyPost();
postRepository.delete(post);
}
}
Hibernate:
call next value for hibernate_sequence
Custom findMyPost
Hibernate:
insert
into
post
(content, created, title, id)
values
(?, ?, ?, ?)
2020-11-16 18:15:49.388 TRACE 1228 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [CLOB] - [null]
2020-11-16 18:15:49.394 TRACE 1228 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [TIMESTAMP] - [null]
2020-11-16 18:15:49.396 TRACE 1228 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [3] as [VARCHAR] - [Hibernate]
2020-11-16 18:15:49.402 TRACE 1228 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [4] as [BIGINT] - [1]
Hibernate:
select
post0_.id as id1_0_,
post0_.content as content2_0_,
post0_.created as created3_0_,
post0_.title as title4_0_
from
post post0_
2020-11-16 18:15:49.426 TRACE 1228 --- [ main] o.h.type.descriptor.sql.BasicExtractor : extracted value ([id1_0_] : [BIGINT]) - [1]
Custom Delete
@Rollback(false) 를 지정하면 딜리트 쿼리를 날리게 된다.
@RunWith(SpringRunner.class)
@DataJpaTest
public class PostRepositoryTest {
@Autowired
private PostRepository postRepository;
@Test
@Rollback(false)
public void crud(){
Post post = new Post();
post.setTitle("Hibernate");
postRepository.save(post);
postRepository.findMyPost();
postRepository.delete(post);
}
}
Hibernate:
call next value for hibernate_sequence
Custom findMyPost
Hibernate:
insert
into
post
(content, created, title, id)
values
(?, ?, ?, ?)
2020-11-16 18:17:35.132 TRACE 6988 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [CLOB] - [null]
2020-11-16 18:17:35.134 TRACE 6988 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [TIMESTAMP] - [null]
2020-11-16 18:17:35.136 TRACE 6988 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [3] as [VARCHAR] - [Hibernate]
2020-11-16 18:17:35.138 TRACE 6988 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [4] as [BIGINT] - [1]
Hibernate:
select
post0_.id as id1_0_,
post0_.content as content2_0_,
post0_.created as created3_0_,
post0_.title as title4_0_
from
post post0_
2020-11-16 18:17:35.164 TRACE 6988 --- [ main] o.h.type.descriptor.sql.BasicExtractor : extracted value ([id1_0_] : [BIGINT]) - [1]
Custom Delete
Hibernate:
delete
from
post
where
id=?
2020-11-16 18:17:35.252 TRACE 6988 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [1]
'springframework > Spring Data JPA' 카테고리의 다른 글
Spring Data Common : Domain Event (0) | 2020.11.17 |
---|---|
Spring Data Common : 공통 리포지토리 커스터마이징 (0) | 2020.11.16 |
Spring Data Common : Async Query Method (0) | 2020.11.16 |
Spring Data Common : 쿼리 작성 (0) | 2020.11.15 |
Spring Data Common : 쿼리 작성 키워드 (0) | 2020.11.15 |