【问题标题】:Spring 'NOT IN' in method naming does not work as it expected方法命名中的 Spring 'NOT IN' 无法按预期工作
【发布时间】:2016-01-21 03:30:13
【问题描述】:

问题

是错误,还是只是我的失败?你能解释一下有什么问题吗?

代码

我创建了简单的 JPARepository

@Repository
interface UserRepository extends JpaRepository<User, Long> {
    User findByName(String name);


    Collection<User> findByIdNotIn(Collection<Long> users);
}

看起来是正确的。如果users 不为空,它会正常工作。但否则它工作不正确:

result = userRepository.findByIdNotIn([]);

它返回空结果,但它应该等于findAll方法调用的结果。

userRepository.findByIdNotIn([]).equals(userRepository.findAll());

还有

为了检查结果,我在方法中添加了@Query 注释

@Repository
interface UserRepository extends JpaRepository<User, Long> {
    User findByName(String name);

    @Query('SELECT u FROM User u WHERE u.id NOT IN ?1')
    Collection<User> findByIdNotIn(Collection<Long> users);
}

在这种情况下,预期结果是正确的。 我也尝试过使用原生 Hibernate CriteriaBuilder

编写查询
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<User> query = builder.createQuery(User.class);
Root<User> root = query.from(User.class);

query.where(builder.not(root.get("id").in([])));
result = entityManager.createQuery(query.select(root)).getResultList();

在这种情况下,预期结果也是正确的。

附加信息

结果休眠查询: 正确结果(使用@Query注解):

Hibernate: select user0_.id as id1_7_, user0_.name as name2_7_ from User user0_ where user0_.id not in  ()

不正确的结果(使用方法命名):

Hibernate: select user0_.id as id1_7_, user0_.name as name2_7_ from User user0_ where user0_.id not in  (?)

我的结论

它看起来像一个 Spring JPA 错误

新的附加信息

我花了一天时间调试spring-data-jpa源代码,发现问题出现在org.springframework.data.jpa.provider.PersistenceProvider方法potentiallyConvertEmptyCollectionHIBERNATE

@Override
        public <T> Collection<T> potentiallyConvertEmptyCollection(Collection<T> collection) {
            return collection == null || collection.isEmpty() ? null : collection;
        }

当集合为空时,此函数返回null 值。 但我发现,如果这个值在空集合上再次替换(在运行时),那么最终结果将是正确的!!!

您对此有任何想法吗?!

【问题讨论】:

    标签: java spring hibernate spring-boot spring-data-jpa


    【解决方案1】:

    来自 JPA 规范 4.6.9 在表达式中:

    逗号分隔列表中必须至少有一个元素定义 IN 的一组值 表达。 如果 IN 或 NOT IN 表达式中 state_field_path_expression 或 in_item 的值为 NULL 或 未知,表达式的值未知。

    所以 Spring JPA 只是遵循 JPA 规范,即使如您所说,人们可以期望没有限制。

    最好在调用正确的存储库方法之前检查您的业务。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-28
      • 2020-05-08
      • 1970-01-01
      • 2017-07-17
      • 2022-10-21
      • 2020-05-02
      • 2017-04-17
      • 1970-01-01
      相关资源
      最近更新 更多