当前位置: 首页 > 知识库问答 >
问题:

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

谭富
2023-03-14

下面是扩展spring PagingAndSortingRepository的示例通用存储库实现,

@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,消息。它抛出的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

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

共有1个答案

闽承望
2023-03-14

就我所读到的内容而言,通过@Query注释告诉新的接口方法要做什么会更容易,而且不必为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 );
...
}

在Spring Data JPA存储库中使用泛型

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

 类似资料:
  • 另一个表是Department表,包含以下列: 下面是表值的示例 为了返回带有状态标签的员工信息,我们需要执行连接: Employee.java Department.java 然后是存储库(DAO):

  • 我已经用@Autowired注释为相应的存储库定义了服务类 存储库接口定义为从JpaReepository扩展 应用程序自动编译服务类 运行时,我得到以下错误

  • 我使用的是Spring Data JPA 1.4.3.RELEASE和Hibernate 4.2.7.Final,我成功地创建了一个基本存储库类,类似于:http://docs . Spring . io/Spring-Data/JPA/docs/1 . 4 . 2 . release/reference/html/repositories . html # repositories . cust

  • 当我们在spring mvc中使用crud存储库时,会出现以下错误

  • 问题内容: 在我的特定情况下,我正在使用区分列策略。这意味着我的JPA实现(hibernate)创建带有特殊 DTYPE 列的 users 表。此列包含实体的类名称。例如,我的 用户 表可以具有 TrialUser* 和 PayingUser的 子类。这些类名称将在 DTYPE 列中,以便EntityManager从数据库加载实体时,它知道要实例化的类的类型。 *** __ 我尝试了两种转换实体类

  • 我有一个通用实体,我想使用JPA持久化,以便它的通用值存储在单个列中。简化的实体类如下所示: 类型唯一标识泛型值的类,并且允许具有相同类的多个类型: 我没有找到如何使用Hibernate保持这种泛型类的方法。我找到了替代方法和变通方法,但它们在我看来并不理想。我考虑了以下选项: > 将值的类型设置为JsonNode,并将其类型类标记为com。弗拉德米尔恰。冬眠类型json。JsonBinaryTy