복붙노트

[SPRING] 모든 저장소와 동시에 다른 사용자 지정 기능에 사용자 지정 기능을 단일 저장소에 추가하는 Spring Jpa

SPRING

모든 저장소와 동시에 다른 사용자 지정 기능에 사용자 지정 기능을 단일 저장소에 추가하는 Spring Jpa

http://docs.spring.io/spring-data/data-jpa/docs/current/reference/html/repositories.html#repositories.custom-implementations 여기에있는 Spring 설명서는 모든 저장소 또는 사용자 정의 기능을 단일 리포지토리가 아니라 둘 다.

Custom Repository Factory Bean을 사용하여 모든 저장소에 사용자 지정 기능을 추가하고 하나의 저장소에만 사용자 지정 기능을 추가하려고한다고 가정 해 보겠습니다 (문서는 사용자 지정 인터페이스와 사용자 지정 Impl을 사용합니다). 내가 어떻게 이걸 얻을 수 있니?

모든 저장소에 "setCurrentTenansInSession"메서드를 추가 한 몇 가지 예제 코드. 이제 맞춤 메소드를 추가하고 싶습니다. "newCustomMethod", 단일 리포지토리 (즉, MyJpaRepository, 내 사용자 지정 리포지토리 팩토리). 어떻게해야합니까?

맞춤 동작 인터페이스 :

@NoRepositoryBean
public interface MyJpaRepository<T, ID extends Serializable> extends JpaRepository<T, ID> { 
    public void setCurrentTenantInSession(Object object);       
}

사용자 정의 동작 구현 :

public class MultiTenantSimpleJpaRepository<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements MyJpaRepository<T, ID> {
    public void setCurrentTenantInSession(Object object) {
        //custom impl
    }
}

사용자 정의 저장소 팩토리 bean :

public class MultiTenantJpaRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable> extends JpaRepositoryFactoryBean<T, S, ID> {

    @Override
    protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
        return new MultiTenantJpaRepositoryFactory(entityManager);
    }
}

마지막으로 사용자 정의 저장소 팩토리 :

public class MultiTenantJpaRepositoryFactory extends JpaRepositoryFactory {
    public MultiTenantJpaRepositoryFactory(EntityManager entityManager) {
        super(entityManager);
    }

    @Override
    protected JpaRepository<?, ?> getTargetRepository(RepositoryMetadata metadata, EntityManager entityManager) {
        final JpaEntityInformation<?, Serializable> entityInformation = getEntityInformation(metadata.getDomainType());

        final SimpleJpaRepository<?, ?> repo = new MultiTenantSimpleJpaRepository(entityInformation, entityManager);

        repo.setLockMetadataProvider(LockModeRepositoryPostProcessor.INSTANCE.getLockMetadataProvider());
        return repo;
    }

    @Override
    protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
        return MultiTenantSimpleJpaRepository.class;
    }
}

해결법

  1. ==============================

    1.언급 한 문서 페이지에서 접근 방식을 결합하면됩니다. Car를 사용자 정의 저장소가있는 엔티티로 설정하십시오.

    언급 한 문서 페이지에서 접근 방식을 결합하면됩니다. Car를 사용자 정의 저장소가있는 엔티티로 설정하십시오.

    CommonCustomRepository는 모든 repos에 추가 된 메소드를 정의합니다.

    @NoRepositoryBean
    public interface CommonCustomRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {
        String getCustomValue();
    }
    

    이 repo 구현 :

    public class CommonCustomRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements CommonCustomRepository<T, ID> {
    
        public CommonCustomRepositoryImpl(Class<T> domainClass, EntityManager em) {
            super(domainClass, em);
        }
    
        public CommonCustomRepositoryImpl(JpaEntityInformation<T, ?> entityInformation,
                EntityManager entityManager) {
            super(entityInformation, entityManager);
        }
    
        @Override
        public String getCustomValue() {
            return "CustomValue";
        }
    
    }
    

    CarRepository의 사용자 정의 메소드

    @NoRepositoryBean
    public interface CustomCarRepository {
    
        public String getCustomCarValue();
    }
    

    주문 자동차 관련 방법의 구현

    public class CarRepositoryImpl implements CustomCarRepository {
    
        @PersistenceContext
        private EntityManager em;
    
        @Override
        public String getCustomCarValue() {
            return "CustomCarValue";
        }
    }
    

    CarRepository의 결합 된 인터페이스

    public interface CarRepository extends CommonCustomRepository<Car, Long>, CustomCarRepository {
    }
    

    문서 에서처럼 사용자 정의 저장소 팩토리

    public class CustomRepositoryFactoryBean<R extends JpaRepository<T, I>, T, I extends Serializable> extends
        JpaRepositoryFactoryBean<R, T, I> {
    
        @Override
        protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
    
            return new CustomRepositoryFactory(entityManager);
        }
    
        private static class CustomRepositoryFactory<T, I extends Serializable> extends JpaRepositoryFactory {
    
            private EntityManager entityManager;
    
            public CustomRepositoryFactory(EntityManager entityManager) {
                super(entityManager);
    
                this.entityManager = entityManager;
            }
    
            @Override
            protected Object getTargetRepository(RepositoryMetadata metadata) {
    
                return new CommonCustomRepositoryImpl<T, I>((Class<T>) metadata.getDomainType(), entityManager);
            }
    
            @Override
            protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
    
                // The RepositoryMetadata can be safely ignored, it is used by the JpaRepositoryFactory
                // to check for QueryDslJpaRepository's which is out of scope.
                return CommonCustomRepositoryImpl.class;
            }
        }
    }
    

    문서의 마지막 구성 비트.

    <jpa:repositories base-package="com.example" factory-class="com.example.CustomRepositoryFactoryBean"/>
    
  2. from https://stackoverflow.com/questions/19765684/spring-jpa-adding-custom-functionality-to-all-repositories-and-at-the-same-time by cc-by-sa and MIT license