2015-11-04 9 views
8

スプリングPagingAndSortingRepositoryを拡張するサンプルジェネリックリポジトリの実装があるため、スプリングサービスにautowiredすることができ、春ブーツでジェネリックJPAリポジトリ実装する方法 - 任意のエンティティ/クラス型ここ

@NoRepositoryBean 
public interface GenericRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID> { 

    public List<T> findByNamedQuery(String name); 
    public List<T> findByNamedQueryAndParams(String name, Map<String, Object> params); 
    public T findOneByNamedQuery(String name); 
    public T findOneByNamedQueryAndParams(String name, Map<String, Object> params); 

}

ファクトリーBeanクラス、

public class GenericRepositoryFactoryBean<R extends JpaRepository<T, I>, T, I extends Serializable> extends 
    JpaRepositoryFactoryBean<R, T, I> { 

    @SuppressWarnings("rawtypes") 
    protected RepositoryFactorySupport createRepositoryFactory(EntityManager em) 
    { 
    return new MyRepositoryFactory(em); 
    } 

    private static class MyRepositoryFactory<T, I extends Serializable> extends JpaRepositoryFactory { 

    private final EntityManager em; 

    public MyRepositoryFactory(EntityManager em) 
    { 
     super(em); 
     this.em = em; 
    } 

    @SuppressWarnings("unchecked") 
    protected Object getTargetRepository(RepositoryMetadata metadata) 
    { 
     return new GenericRepositoryImpl<T, I>((Class<T>) metadata.getDomainType(), em); 
    } 

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

実装クラス、

public final class GenericRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements 
    GenericRepository<T, ID> { 

    private final EntityManager em; 
    private final Class<T> domainClass; 

    public GenericRepositoryImpl(Class<T> domainClass, EntityManager entityManager) 
    { 
     super(domainClass, entityManager); 
     this.em = entityManager; 
     this.domainClass = domainClass; 
    } 

    @Override 
    public List<T> findByNamedQuery(final String name) 
    { 
     validate(name); 
     return this.em.createNamedQuery(name, domainClass).getResultList(); 
    } 

    @Override 
    public T findOneByNamedQuery(String name) 
    { 
     validate(name); 
     return this.em.createNamedQuery(name, domainClass).getSingleResult(); 
    } 

    @Override 
    public List<T> findByNamedQueryAndParams(String name, Map<String, Object> params) 
    { 
     validate(name, params); 
     final TypedQuery<T> query = this.em.createQuery(name, domainClass); 
     setParams(query, params); 
     return query.getResultList(); 
    } 

} 

したがって、GenericRepositoryをCustomer.java、Message.javaなどのさまざまなタイプのサービスにAutowireしようとすると、少なくとも1つのBeanタイプのインタフェースGenericRepositoryが必要です。これは、顧客とメッセージの両方のタイプの個別リポジトリを作成する場合に機能します。複数のリポジトリを作成せずに、私はこれを実装することができません。

@Service 
@Transactional(noRollbackFor = Exception.class) 
public class CustomerService { 

@Autowired 
private GenericRepository<Customer, Serializable> cr; works fine with just one entity type 

@Autowired 
private GenericRepository<Message, Serializable> cr; throws exception 

100の以上のエンティティクラスを持っている場合は、私はリポジトリとその悪いの100年代を作成してしまいます。これを行うより良い方法があれば教えてください。私は何@queryアノテーションで行うにしてたBeanFactoryやIMPLを自分で気にしない新しいインターフェイスメソッドを伝えるために容易になります読んだことについては

+0

私はまったく同じ状況にあります。あなたを助けるものは見つかりましたか?ありがとう! – Moltes

+0

あなたはこれを実装する方法を見つけましたか?私は同じ状況にいる。 – Sannu

答えて

3

...

@Repository 
public interface GenericRepository<T, ID extends Serializable> extends JpaRepository<T, ID> { 
@Query(value = "SELECT c FROM customers c WHERE c.name = :name") 
public List<T> findByNamedQuery(String name); 
... 
} 

Using generics in Spring Data JPA repositories

それはあなたには当てはまりませんし、あなたのコードが1つのリポジトリで動作すると言っていますが、2番目に追加したときに失敗すると言っているのは、Beanのスコープをプロトタイプにしようとすることです。私は本当に助けていない場合はごめんなさい、あまりにも私を憎むことはありません^^

関連する問題