Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/382.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在Spring Boot中实现通用JPA存储库-它可以自动连接到任何实体/类类型的Spring服务中_Java_Spring_Jpa_Spring Boot_Spring Data Jpa - Fatal编程技术网

Java 如何在Spring Boot中实现通用JPA存储库-它可以自动连接到任何实体/类类型的Spring服务中

Java 如何在Spring Boot中实现通用JPA存储库-它可以自动连接到任何实体/类类型的Spring服务中,java,spring,jpa,spring-boot,spring-data-jpa,Java,Spring,Jpa,Spring Boot,Spring Data Jpa,下面是扩展spring Paging和SortingRepository的示例通用存储库实现 @NoRepositoryBean public interface GenericRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID> { public List<T> findByNamedQuery( String name ); public

下面是扩展spring Paging和SortingRepository的示例通用存储库实现

@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 );
@NoRepositoryBean
公共接口GenericRepository扩展了分页和排序存储库{
公共列表findByNamedQuery(字符串名称);
公共列表findByNamedQueryAndParams(字符串名称、映射参数);
公共T findOneByNamedQuery(字符串名称);
公共T findOneByNamedQueryAndParams(字符串名称、映射参数);
}

工厂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;
    }
  }
}
公共类GenericRepositoryFactoryBean扩展
JpaRepositoryFactoryBean{
@抑制警告(“原始类型”)
受保护的RepositoryFactorySupport createRepositoryFactory(EntityManager em)
{
返回新的MyRepositoryFactory(em);
}
私有静态类MyRepositoryFactory扩展了JpaRepositoryFactory{
私人最终实体经理em;
公共MyRepositoryFactory(实体管理器em)
{
超级(em);
this.em=em;
}
@抑制警告(“未选中”)
受保护对象GetTargetPository(RepositoryMetadata元数据)
{
返回新的GenericRepositoryImpl((类)metadata.getDomainType(),em);
}
受保护类getRepositoryBaseClass(RepositoryMetadata元数据)
{
返回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();
   }

}
public final类GenericRepositoryImpl扩展了SimpleParepository实现
一般保存{
私人最终实体经理em;
私有最终类domainClass;
公共GenericRepositoryImpl(类domainClass,EntityManager EntityManager)
{
超级(域类、实体管理器);
this.em=实体管理器;
this.domainClass=domainClass;
}
@凌驾
公共列表findByNamedQuery(最终字符串名)
{
验证(名称);
返回此.em.createNamedQuery(名称,domainClass).getResultList();
}
@凌驾
public T findOneByNamedQuery(字符串名称)
{
验证(名称);
返回此.em.createNamedQuery(名称,domainClass).getSingleResult();
}
@凌驾
公共列表findByNamedQueryAndParams(字符串名称、映射参数)
{
验证(名称、参数);
final TypedQuery query=this.em.createQuery(名称,域类);
setParams(查询,参数);
返回query.getResultList();
}
}
因此,当我尝试将GenericRepository自动连接到不同类型(如Customer.java、Message.java等)的服务时,它至少需要一种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
@服务
@事务性(norollboor=Exception.class)
公共类客户服务{
@自动连线
私有GenericRepository cr;仅适用于一种实体类型
@自动连线
私有GenericRepository cr;引发异常

如果有100个或更多的实体类,那么我最终会创建100个存储库,这是不好的。请告诉我是否有更好的方法来做到这一点。

对于我所阅读的内容,通过@Query annotation告诉新的接口方法要做什么会更容易,并且不必为BeanFactory或impl

 @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 );
...
}
@存储库
公共接口GenericRepository扩展了JpaRepository{
@查询(value=“从客户c中选择c,其中c.name=:name”)
公共列表findByNamedQuery(字符串名称);
...
}


如果这不适用于你,你是说你的代码只在一个存储库中工作,但当你添加第二个存储库时失败了,我的第一个想法是尝试将bean的范围设置为原型,但这只是一种推测。如果我没有真的帮助你,我很抱歉,不要太恨我^ ^

我也处于完全相同的情况。你发现了什么吗帮你们?谢谢!你们知道怎么实现吗?我的情况也一样。