2013-11-04 15 views
6

Tài liệu mùa xuân ở đây http://docs.spring.io/spring-data/data-jpa/docs/current/reference/html/repositories.html#repositories.custom-implementations cho ví dụ để thêm chức năng tùy chỉnh vào tất cả các kho lưu trữ hoặc một kho lưu trữ duy nhất, không phải cả hai.Spring Jpa thêm chức năng tùy chỉnh vào tất cả các kho và đồng thời các func khác tùy chỉnh vào một kho lưu trữ

Giả sử tôi muốn thêm một số func tùy chỉnh vào tất cả các kho lưu trữ (sử dụng Nhà máy sản xuất kho lưu trữ tùy chỉnh) và một số khác chỉ cho một kho lưu trữ duy nhất (tài liệu nói sử dụng Giao diện tùy chỉnh và Custom Impl); Làm thế nào tôi có thể đạt được điều này?

Một số mã mẫu mà tôi đã thêm phương thức "setCurrentTenansInSession" vào tất cả các kho lưu trữ; bây giờ tôi muốn thêm phương thức tùy chỉnh, ví dụ: "newCustomMethod", để ona đơn kho lưu trữ (đó là một MyJpaRepository, như cho nhà máy kho tùy chỉnh của tôi). Làm thế nào để tôi làm điều này?

giao diện hành vi tùy chỉnh:

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

thực hiện hành vi tùy chỉnh:

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

Tuỳ chỉnh kho bean factory:

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

Và cuối cùng nhà máy kho tùy chỉnh:

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

Trả lời

11

Bạn chỉ cần kết hợp các phương pháp trên trang tài liệu mà bạn đã đề cập. Hãy để Car là thực thể bạn muốn có kho lưu trữ tùy chỉnh.

CommonCustomRepository xác định phương pháp thêm vào tất cả các hợp đồng mua:

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

Việc thực hiện cho repo này:

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

} 

phương pháp tuỳ chỉnh cho CarRepository

@NoRepositoryBean 
public interface CustomCarRepository { 

    public String getCustomCarValue(); 
} 

Thực hiện các tùy chỉnh car- các phương pháp liên quan

public class CarRepositoryImpl implements CustomCarRepository { 

    @PersistenceContext 
    private EntityManager em; 

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

Giao diện kết hợp cho nhà máy repo CarRepository

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

Tuỳ chỉnh, giống như trong tài liệu

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

Các bit cuối cùng của cấu hình, giống như trong các tài liệu

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

Cảm ơn rất nhiều kkamenev! – lincetto

+2

Kể từ 'spring-data-commons' 1.11 chỉ định' base-class = "com.example.CommonCustomRepositoryImpl" 'thay vì thuộc tính' factory-class' không được chấp nhận cho 'jpa: repositories'. Nhà máy là không cần thiết khi xác định lớp cơ sở. –

Các vấn đề liên quan