2013-11-04 9 views
6

ここでは春のドキュメントhttp://docs.spring.io/spring-data/data-jpa/docs/current/reference/html/repositories.html#repositories.custom-implementationsは、すべてのリポジトリまたは単一のリポジトリにカスタム機能を追加する例を示します。Spring Jpaはすべてのリポジトリに同時にカスタム機能を追加します。

カスタムリポジトリファクトリ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 
    } 
} 

カスタムリポジトリ工場豆:

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; 
    } 
} 

答えて

11

あなたが言及したドキュメントページのアプローチを組み合わせるだけです。 Carを、カスタムリポジトリを作成するエンティティにします。

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

このレポのための実装:

CommonCustomRepositoryは、すべてのリポジトリに追加されたメソッドを定義するカスタムのCarRepository

@NoRepositoryBean 
public interface CustomCarRepository { 

    public String getCustomCarValue(); 
} 

実装のための

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"; 
    } 

} 

カスタムメソッドをカルボ関連する方法

public class CarRepositoryImpl implements CustomCarRepository { 

    @PersistenceContext 
    private EntityManager em; 

    @Override 
    public String getCustomCarValue() { 
     return "CustomCarValue"; 
    } 
} 

だけドキュメント

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; 
     } 
    } 
} 

単にドキュメントのような構成の最終ビット、のようCarRepository

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

カスタムレポ工場用複合インタフェース、

<jpa:repositories base-package="com.example" factory-class="com.example.CustomRepositoryFactoryBean"/> 
+0

ありがとうkkamenev! – lincetto

+2

'spring-data-commons'の時点で、' jpa:repositories'の 'factory-class'属性の代わりに' base-class = "com.example.CommonCustomRepositoryImpl" 'を指定してください。基底クラスを指定するときは、ファクトリは不要です。 –

関連する問題