아카이브

[스프링 데이터 JPA] 스프링 데이터 JPA 9. Specifications 본문

Spring/스프링 데이터 JPA

[스프링 데이터 JPA] 스프링 데이터 JPA 9. Specifications

주멘이 2021. 1. 17. 12:56

에릭 에반스의 책 DDD에서 언급하는 Specification 개념을 차용한 것으로 QueryDSL의 Predicate와 비슷합니다.

장점

  • 서버쪽 설정이 필요하지만, 클라이언트 코드가 간결해진다.
  • Spec 정의에 따라 가독성이 달라진다.
  • QueryDSL의 predicate와 Specification을 사용하여 Repository에 쿼리 메서드를 간결하게 구성할 수 있다.
  • 다양한 기능을 구현할 수 있다. (대신 테스트가 철저해야 함)

 

 

설정하는 방법

https://docs.jboss.org/hibernate/stable/jpamodelgen/reference/en-US/html_single/

 

Hibernate JPA 2 Metamodel Generator

The structure of the metamodel classes is described in the [JPA 2 Specification], but for completeness the definition is repeated in the following paragraphs. Feel free to skip ahead to Chapter 2, Usage if you are not interested into the gory details. The

docs.jboss.org

pom.xml에 의존성과 플러그인 설정

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-jpamodelgen</artifactId>
</dependency>

<!-- 플러그인 -->
<plugin>
    <groupId>org.bsc.maven</groupId>
    <artifactId>maven-processor-plugin</artifactId>
    <version>2.0.5</version>
    <executions>
        <execution>
            <id>process</id>
            <goals>
                <goal>process</goal>
            </goals>
            <phase>generate-sources</phase>
            <configuration>
                <processors>                                
                    <processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor>
                </processors>
            </configuration>
        </execution>
    </executions>
    <dependencies>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-jpamodelgen</artifactId>
            <version>${hibernate.version}</version>
        </dependency>
    </dependencies>
</plugin>

 

Intellij에 어노테이션 프로세서 설정

  • Enable annotation processing 체크
  • Annotation Processors에 org.hibernate.jpamodelhen.JPAMetaModelEntityProcessor 추가
  • Maven clean 후 build 하면 target/generated-sources/annotations에 파일이 추가된다

CommentRepository에 JpaSpecificationExecutor 추가하기

public interface CommentRepository extends MyRepository<Comment, Long>, JpaSpecificationExecutor<Comment> {
}

CommentSpecs 클래스 생성하기

public class CommentSpecs {

    // comment가 best인지 판단하는 스펙
    public static Specification<Comment> isBest() {
        return (root, query, builder) ->
                builder.isTrue(root.get(Comment_.best));
    }

    // comment가 up이 10이상인지 판단하는 스펙
    public static Specification<Comment> isGood() {
        return (root, query, builder) ->
                builder.greaterThanOrEqualTo(root.get(Comment_.up), 10);
    }
}

테스트 코드

    @Test
    public void specs() {
        Page<Comment> page = commentRepository
                .findAll(isBest().or(isGood()), PageRequest.of(0, 10));

    }