【问题标题】:Spring Data repository: set fetch size as a parameterSpring Data repository:将获取大小设置为参数
【发布时间】:2020-05-29 15:21:27
【问题描述】:

我有一个这样的 Spring Data 存储库:

public interface MyRepo extends JpaRepository<MyEntity, Long> {

    @QueryHints(@javax.persistence.QueryHint(name="org.hibernate.fetchSize", value="${fetch.size}"))
    List<MyEntity> findAll();

}

我将 fetch.size=100 添加到 application.properties 中,但出现此错误:

java.lang.NumberFormatException: For input string: "${fetch.size}"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    at java.lang.Integer.parseInt(Integer.java:569)
    at java.lang.Integer.valueOf(Integer.java:766)
    at org.hibernate.jpa.internal.util.ConfigurationHelper.getInteger(ConfigurationHelper.java:81)
    at org.hibernate.query.internal.AbstractProducedQuery.setHint(AbstractProducedQuery.java:1035)
    at org.hibernate.query.internal.AbstractProducedQuery.setHint(AbstractProducedQuery.java:106)
    at org.hibernate.query.criteria.internal.compile.CriteriaQueryTypeQueryAdapter.setHint(CriteriaQueryTypeQueryAdapter.java:145)
    at org.hibernate.query.criteria.internal.compile.CriteriaQueryTypeQueryAdapter.setHint(CriteriaQueryTypeQueryAdapter.java:59)
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.applyQueryHints(SimpleJpaRepository.java:766)
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.applyRepositoryMethodMetadata(SimpleJpaRepository.java:758)
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.getQuery(SimpleJpaRepository.java:678)
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.getQuery(SimpleJpaRepository.java:655)
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll(SimpleJpaRepository.java:346)

Spring 是否支持这种类型的属性注入?

【问题讨论】:

    标签: spring hibernate dependency-injection spring-data


    【解决方案1】:

    简短的回答是:您不能在QueryHints 注释中包含动态值。可以这样做:

    @QueryHints(@javax.persistence.QueryHint(name="org.hibernate.fetchSize", value="" + Integer.MAX_VALUE))
    

    但是,正如Integer.MAX_VALUE,只允许使用常量。

    所以基本上你有以下选择:


    将其包含在属性文件中

    在您的属性文件中添加所需的值,如您所见here


    获取内部实体管理器

    这里你必须面对两个主要问题:

    1. 在查询中包含所需的 fetchSize 值。
    2. 从属性文件中获取fetchSize 值并在接口中使用它。

    对于第二个,您可以查看解决方法here。一个更简单的例子:

    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
    
    @Component
    public class Constant {
    
      public static int FETCH_SIZE;
    
      @Value("${fetch.size}")
      public void setFetchSizeStatic(int fetchSize){
        Constant.FETCH_SIZE = fetchSize;
      }
    }
    

    对于第一点,需要进行更多更改:

    1.1 创建自定义Repository 以访问EntityManager

    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.data.repository.NoRepositoryBean;
    
    import javax.persistence.EntityManager;
    import java.io.Serializable;
    
    @NoRepositoryBean
    public interface ExtendedJpaRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {
    
      /**
       * Return the internal {@link EntityManager} to provide more functionality to the repositories
       *
       * @return {@link EntityManager}
       */
      EntityManager getEntityManager();
    }
    
    
    
    import org.springframework.data.jpa.repository.support.JpaEntityInformation;
    import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
    
    import javax.persistence.EntityManager;
    import java.io.Serializable;
    
    public class ExtendedJpaRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements ExtendedJpaRepository<T, ID> {
    
      private EntityManager entityManager;
    
      public ExtendedJpaRepositoryImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {
        super(entityInformation, entityManager);
        this.entityManager = entityManager;
      }
    
    
      @Override
      public EntityManager getEntityManager() {
        return entityManager;
      }
    }
    

    1.2 配置新的存储库:

    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
    
    @Configuration
    @EnableJpaRepositories(basePackages = "PATH_TO_YOUR_REPOSITORIES", repositoryBaseClass = ExtendedJpaRepositoryImpl.class)
    public class PersistenceConfiguration { }
    

    现在可以创建自定义Repository,为提示配置动态值:

    import org.hibernate.jpa.QueryHints;
    
    @Repository
    public interface MyEntityRepository extends ExtendedJpaRepository<MyEntity, Long> {
    
      default List<MyEntity> findAll() {
        return getEntityManager().createQuery("select e "
                                            + "from MyEntity e ", MyEntity.class)
                .setHint( QueryHints.HINT_FETCH_SIZE, Constant.FETCH_SIZE )
                .getResultList();
      }
    }
    

    【讨论】:

    猜你喜欢
    • 2013-12-15
    • 2014-09-02
    • 2021-03-13
    • 2015-10-28
    • 1970-01-01
    • 2016-05-07
    • 2018-01-24
    • 2017-11-23
    • 1970-01-01
    相关资源
    最近更新 更多