Spring 批处理 - RepositoryItemReaderBuilder with RepositoryMethodReference throws Cannot subclass final class
Spring Batch - RepositoryItemReaderBuilder with RepositoryMethodReference throws Cannot subclass final class
我正在尝试使用 Spring 以 RepositoryMethodReference 作为参数的批处理 RepositoryItemReaderBuilder 来提供调用存储库方法的类型安全方式。
不幸的是我无法完成这项工作,因为这会抛出
java.lang.IllegalArgumentException: Cannot subclass final class com.sun.proxy.$Proxy100
据我了解,要使这个工作存储库不应该是最终的,但我该怎么做?
implementation 'org.springframework.batch:spring-batch-core:4.3.5'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa:2.6.7'
@Entity
public class Customer {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String firstName;
...constructors, getters, setters
}
public interface CustomerRepository extends PagingAndSortingRepository<Customer, Long> {
}
@SpringBootApplication
public class AccessingDataJpaApplication {
public static void main(String[] args) {
SpringApplication.run(AccessingDataJpaApplication.class);
}
@Bean
public CommandLineRunner demo(CustomerRepository repository) {
return (args) -> {
Customer customer = new Customer();
customer.setFirstName("John");
repository.save(customer);
RepositoryItemReaderBuilder.RepositoryMethodReference<CustomerRepository> repositoryMethodReference =
new RepositoryItemReaderBuilder.RepositoryMethodReference<>(repository);
repositoryMethodReference.methodIs().findAll();
RepositoryItemReader<Customer> reader = new RepositoryItemReaderBuilder<Customer>()
.repository(repositoryMethodReference)
.sorts(Collections.singletonMap("id", Sort.Direction.ASC))
.maxItemCount(5)
.name("bar").build();
Customer read = reader.read();
};
}
}
解决方法是创建
public class PagingAndSortingRepositoryWrapper<T, ID> implements PagingAndSortingRepository<T, ID> {
private PagingAndSortingRepository<T, ID> pagingAndSortingRepository;
public PagingAndSortingRepositoryWrapper() {
}
public PagingAndSortingRepositoryWrapper(PagingAndSortingRepository<T, ID> pagingAndSortingRepository) {
this.pagingAndSortingRepository = pagingAndSortingRepository;
}
@Override
public Iterable<T> findAll(Sort sort) {
return pagingAndSortingRepository.findAll(sort);
}
@Override
public Page<T> findAll(Pageable pageable) {
return pagingAndSortingRepository.findAll(pageable);
}
...
那么 repositoryWrapper 将不是最终的,我们将能够使用 RepositoryMethodReference
PagingAndSortingRepositoryWrapper<Customer, Long> repositoryWrapper = new PagingAndSortingRepositoryWrapper<>(customerRepository);
RepositoryItemReaderBuilder.RepositoryMethodReference<PagingAndSortingRepositoryWrapper> repositoryMethodReference =
new RepositoryItemReaderBuilder.RepositoryMethodReference<>(repositoryWrapper);
repositoryMethodReference.methodIs().findAll();
RepositoryItemReader<Customer> itemReader = new RepositoryItemReaderBuilder<Customer>()
.repository(repositoryMethodReference)
.name("bar")
.sorts(Collections.singletonMap("id", Sort.Direction.ASC))
.build();
我正在尝试使用 Spring 以 RepositoryMethodReference 作为参数的批处理 RepositoryItemReaderBuilder 来提供调用存储库方法的类型安全方式。
不幸的是我无法完成这项工作,因为这会抛出
java.lang.IllegalArgumentException: Cannot subclass final class com.sun.proxy.$Proxy100
据我了解,要使这个工作存储库不应该是最终的,但我该怎么做?
implementation 'org.springframework.batch:spring-batch-core:4.3.5'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa:2.6.7'
@Entity
public class Customer {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String firstName;
...constructors, getters, setters
}
public interface CustomerRepository extends PagingAndSortingRepository<Customer, Long> {
}
@SpringBootApplication
public class AccessingDataJpaApplication {
public static void main(String[] args) {
SpringApplication.run(AccessingDataJpaApplication.class);
}
@Bean
public CommandLineRunner demo(CustomerRepository repository) {
return (args) -> {
Customer customer = new Customer();
customer.setFirstName("John");
repository.save(customer);
RepositoryItemReaderBuilder.RepositoryMethodReference<CustomerRepository> repositoryMethodReference =
new RepositoryItemReaderBuilder.RepositoryMethodReference<>(repository);
repositoryMethodReference.methodIs().findAll();
RepositoryItemReader<Customer> reader = new RepositoryItemReaderBuilder<Customer>()
.repository(repositoryMethodReference)
.sorts(Collections.singletonMap("id", Sort.Direction.ASC))
.maxItemCount(5)
.name("bar").build();
Customer read = reader.read();
};
}
}
解决方法是创建
public class PagingAndSortingRepositoryWrapper<T, ID> implements PagingAndSortingRepository<T, ID> {
private PagingAndSortingRepository<T, ID> pagingAndSortingRepository;
public PagingAndSortingRepositoryWrapper() {
}
public PagingAndSortingRepositoryWrapper(PagingAndSortingRepository<T, ID> pagingAndSortingRepository) {
this.pagingAndSortingRepository = pagingAndSortingRepository;
}
@Override
public Iterable<T> findAll(Sort sort) {
return pagingAndSortingRepository.findAll(sort);
}
@Override
public Page<T> findAll(Pageable pageable) {
return pagingAndSortingRepository.findAll(pageable);
}
...
那么 repositoryWrapper 将不是最终的,我们将能够使用 RepositoryMethodReference
PagingAndSortingRepositoryWrapper<Customer, Long> repositoryWrapper = new PagingAndSortingRepositoryWrapper<>(customerRepository);
RepositoryItemReaderBuilder.RepositoryMethodReference<PagingAndSortingRepositoryWrapper> repositoryMethodReference =
new RepositoryItemReaderBuilder.RepositoryMethodReference<>(repositoryWrapper);
repositoryMethodReference.methodIs().findAll();
RepositoryItemReader<Customer> itemReader = new RepositoryItemReaderBuilder<Customer>()
.repository(repositoryMethodReference)
.name("bar")
.sorts(Collections.singletonMap("id", Sort.Direction.ASC))
.build();