方法中从 spring-data-jpa 2.7.1 迁移到 3.1.2(SpringBoot 3.1.2 迁移)后:
@Query("SELECT o FROM Storage o WHERE o.status = 'SUCCESS' " +
" AND ((:referenceNumbers) IS NULL OR o.referenceNumber IN (:referenceNumbers)) " +"...")
Page<Storage> findObject(ObjectFilter filter, Set<String> referenceNumbers, Iterable<Long> systemIds,Pageable pageable);
@Entity
@Getter
@Setter
@RequiredArgsConstructor
@EqualsAndHashCode
@Accessors(chain = true)
class Storage{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String referenceNumber;
@Enumerated(EnumType.STRING)
private Status status;
}
我得到:
org.springframework.orm.jpa.JpaSystemException:请求未知的换行转换:java.util.ImmutableCollections$Set12 到 java.lang.String :
org.hibernate.type.descriptor.java.StringJavaType
(java.lang.String)
IN 方法似乎无法再处理 Collection 了
我试图找到 JPQL IN 方法的文档,但找不到任何相关的内容
对于 2.7.1 语法,此方法工作得非常好。
看起来
(:referenceNumbers) IS NULL
就是问题所在。
您可以将查询方法分为两种方法,一种方法具有用于处理该问题的自定义逻辑:
@Query("SELECT o FROM Storage o WHERE o.status = 'SUCCESS' " +
" AND (:ignoreReferenceNumbers OR o.referenceNumber IN (:referenceNumbers)) " +"...")
Page<Storage> findObjectInternal(ObjectFilter filter, Set<String> referenceNumbers, boolean ignoreReferenceNumbers, Iterable<Long> systemIdsPageable pageable);
default Page<Storage> findObject(ObjectFilter filter, Set<String> referenceNumbers, Iterable<Long> systemIds,Pageable pageable){
if(referenceNumbers==null){
return findObjectInternal(filter, Collections.emptyList(), true, systemIds, pageable);
}
return findObjectInternal(filter, referenceNumbers, false, systemIds, pageable);
}
或使用两种(重载)
default
方法:
@Query("SELECT o FROM Storage o WHERE o.status = 'SUCCESS' " +
" AND (:ignoreReferenceNumbers OR o.referenceNumber IN (:referenceNumbers)) " +"...")
Page<Storage> findObjectInternal(ObjectFilter filter, Set<String> referenceNumbers, boolean ignoreReferenceNumbers, Iterable<Long> systemIdsPageable pageable);
default Page<Storage> findObject(ObjectFilter filter, Set<String> referenceNumbers, Iterable<Long> systemIds,Pageable pageable){
return findObjectInternal(filter, referenceNumbers, false, systemIds, pageable);
}
default Page<Storage> findObject(ObjectFilter filter, Iterable<Long> systemIds,Pageable pageable){
return findObjectInternal(filter, Collections.emptyList(), true, systemIds, pageable);
}
并始终调用相应的默认方法,而不是使用
null
参数。