2013-11-04 22 views
6

Yay belgeleri burada http://docs.spring.io/spring-data/data-jpa/docs/current/reference/html/repositories.html#repositories.custom-implementations belgelerine, her iki havuzda da değil, tüm depolara veya tek bir depoya özel işlevsellik eklemek için örnek verir.Spring Jpa, tüm depolara özel işlevler ekleyerek ve aynı zamanda diğer özel işlevler için tek bir depoya

Tüm depolara (Özel Depo Fabrikası Bean'i kullanılarak) bazı özel işlevler eklemek ve sadece tek bir depoya (örneğin, bir Özel Arabirim ve bir Özel Impl kullanacağını söylüyor) bazı özel işlevler eklemek istiyorum; Bunu nasıl başarabilirim?

Tüm kod havuzlarına "setCurrentTenansInSession" yöntemini eklediğim bazı örnek kodlar; şimdi özel bir yöntem eklemek istiyorum, ör. "newCustomMethod", tek bir depoda (bu benim özel depo fabrikamda olduğu gibi bir MyJpaRepository). Bunu nasıl yaparım?

Özel davranış arayüzü:

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

Özel davranışı uygulaması:

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

Özel depo fabrika fasulye:

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

Ve nihayet özel depo fabrika:

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

cevap

11

Yalnızca yaklaşımları, belirttiğiniz dokümanda birleştirmeniz gerekir. Özel bir deponuz olmasını istediğiniz varlık Car olsun.

CommonCustomRepository

tüm repo eklenen yöntemi tanımlar:

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

bu repo uygulanması: özel Car-CarRepository

@NoRepositoryBean 
public interface CustomCarRepository { 

    public String getCustomCarValue(); 
} 

Uygulanması İçin

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

} 

Özel yöntemleri ilgili yöntemler

public class CarRepositoryImpl implements CustomCarRepository { 

    @PersistenceContext 
    private EntityManager em; 

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

sadece dokümantasyon

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

sadece docs gibi konfigürasyonun son bit, gibi CarRepository

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

Özel Repo fabrikası için kombine arayüzü,

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

Çok teşekkürler kkamenev! – lincetto

+2

"Spring-data-commons" 1.11 'jpa: depositods' için 'fabrika sınıfı' özelliğini kullanımdan kaldırılmış yerine 'base-class = "com.example.CommonCustomRepositoryImpl" 'belirtin. Baz sınıfı belirlenirken fabrikaya gerek yoktur. –