【问题标题】:How to inject configuration in a custom Spring Data JPA repository如何在自定义 Spring Data JPA 存储库中注入配置
【发布时间】:2018-01-09 18:48:54
【问题描述】:

我想将基于 JPA batch inserts with Hibernate & Spring Data 中的代码的自定义批量保存方法添加到我的应用程序中的所有 Spring Data JPA 存储库。 Spring Data doc explains how this can be done 具有自定义存储库基类,如下所示。我的问题是如何在下面的示例中设置 batchSize 属性。如下所示使用@Value 注入不起作用。

@NoRepositoryBean
public interface BulkRepository<T, ID extends Serializable>
  extends JpaRepository<T, ID> {

  void bulkSave(Iterable<T> entities);
}

public class BulkRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements BulkRepository<T, ID> {

  private final EntityManager entityManager;

  @Value("${spring.jpa.properties.hibernate.jdbc.batch_size}")
  private int batchSize;

  public BulkRepositoryImpl(JpaEntityInformation entityInformation,
                          EntityManager entityManager) {
    super(entityInformation, entityManager);   
     this.entityManager = entityManager;
  }

  public void bulkSave(Iterable<T> entities) {
    // implementation using batchSize goes here
  }
}

我是否必须使用自定义 JpaRepositoryFactoryBean 来构建已配置的 BulkRepositoryImpl?还是有更直接的方法?

【问题讨论】:

  • 如何设置“spring.jpa.properties.hibernate.jdbc.batch_size”值?
  • "spring.jpa.properties.hibernate.jdbc.batch_size" 在 application.properties 中设置。我的问题是如何将值从那里获取到 BulkRepositoryImpl 实例中。
  • 你得到的错误是什么?
  • BulkRepositoryImpl 创建没有错误。问题只是没有设置batchSize(默认值为0)。
  • 您是否尝试通过构造函数注入值?

标签: java spring repository spring-data-jpa


【解决方案1】:

您可以从 EntityManager 获取它。

String defaultBatchSize = "100";
String batchSizeString = (String) entityManager.getEntityManagerFactory().getProperties()
                         .getOrDefault("hibernate.jdbc.batch_size", defaultBatchSize);
batchSize = Integer.parseInt(batchSizeString);

【讨论】:

    【解决方案2】:

    我遇到了完全相同的问题,找不到任何方法来定义我自己的 JpaRepositoryFactoryBean 类。似乎自定义存储库基类的依赖项不会像在标准 bean 中那样自动注入(参见herehere)。此外,在创建存储库接口的实例时,默认的JpaRepositoryFactory 仅将JpaEntityInformationEntityManager 的实例传递给类构造函数(请参阅here)。据我所知,这有效地阻止了您为扩展 SimpleJpaRepository 的类添加额外的依赖项。

    我最终通过以下方式定义了自定义工厂:

    @Configuration
    @ConfigurationProperties(prefix = "spring.jpa.properties.hibernate.jdbc")
    public class RepositoryConfiguration {
        private int batchSize;
    }
    
    public class MyCustomRepositoryFactoryBean<R extends JpaRepository<T, I>, T, I extends Serializable> extends JpaRepositoryFactoryBean<R, T, I> {
    
        private RepositoryConfiguration repositoryConfiguration;
    
        public MyCustomRepositoryFactoryBean(Class<? extends R> repositoryInterface, RepositoryConfiguration repositoryConfiguration) {
            super(repositoryInterface);
            this.repositoryConfiguration = repositoryConfiguration;
        }
    
        @Override
        protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
            return new MyCustomRepositoryFactory(entityManager, repositoryConfiguration);
        }
    
        private static class MyCustomRepositoryFactory<T, I extends Serializable> extends JpaRepositoryFactory {
    
            private RepositoryConfiguration repositoryConfiguration;
    
            MyCustomRepositoryFactory(EntityManager entityManager, RepositoryConfiguration repositoryConfiguration) {
                super(entityManager);
                this.repositoryConfiguration = repositoryConfiguration;
            }
    
            @Override
            @SuppressWarnings("unchecked")
            protected SimpleJpaRepository<?, ?> getTargetRepository(RepositoryInformation information, 
                    EntityManager entityManager) {
    
                JpaEntityInformation<T, ?> entityInformation = 
                        (JpaEntityInformation<T, ?>) getEntityInformation(information.getDomainType());
    
                return new MyCustomRepositoryImpl<T, I>(
                        entityInformation, 
                        entityManager, 
                        repositoryConfiguration);
            }
    
            @Override
            protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
                return MyCustomRepositoryImpl.class;
            }
        }
    }
    

    虽然也不能在MyCustomRepositoryFactoryBean 中注入带有@Value 的字段,但Spring 会解析传递给构造函数的依赖项,因此您只需通过bean 提供属性(上面代码中的RepositoryConfiguration)和将其传递给MyCustomRepositoryImpl。最后,您需要通过添加来指示 Spring Data 在创建存储库时使用您的 FactoryBean

    @EnableJpaRepositories(
            repositoryFactoryBeanClass = MyCustomRepositoryFactoryBean.class
    )
    

    @Configuration 注释的bean。这是很多样板,但它确实有效。

    注意我正在使用spring-data-jpa:1.11.8.RELEASE

    【讨论】:

      猜你喜欢
      • 2018-10-06
      • 2015-09-28
      • 2021-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-28
      • 1970-01-01
      • 2012-06-02
      相关资源
      最近更新 更多