Spring JPA 标准构建器大于:我可以传递字符串值以比较数据库中的数字类型吗

Posted

技术标签:

【中文标题】Spring JPA 标准构建器大于:我可以传递字符串值以比较数据库中的数字类型吗【英文标题】:Spring JPA criteria builder greaterThan : Can I pass String value for comparing Number type in database 【发布时间】:2021-12-21 04:45:30 【问题描述】:

我正在使用 Spring Data JPA 标准构建器 greaterThan API 进行比较。

数据库字段rating 的类型为NUMBER(5,0)。实体类有一个rating 类型为Integer 的字段。我正在传递String 类型的值进行比较。

即使我没有传递Integer 值进行比较,它仍然返回有效结果。请帮助我了解这是怎么可能的。

是不是说,当数据库中字段的实际数据类型是不同类型时,我可以将数据库字段的javaString版本传递给greaterThan方法。

我的比较代码块看起来像这样

CriteriaBuilder cb = entityManager.getCriteriaBuilder();

CriteriaQuery cq = cb.createQuery();

Root<Customer> root = cq.from(Customer.class);
//you can see here , value 20 I am passing as String
Predicate comparisonPredicate = cb.greaterThan(root.get("rating"), "20");

cq.where(comparisonPredicate );

cq.select(root);

TypedQuery<Customer> query = entityManager.createQuery(cq);

【问题讨论】:

在过程中的某个时刻(在 Java 或 Oracle SQL 引擎中),将尝试将值从字符串转换为数字的隐式转换。你可以直接在Oracle中使用SELECT * FROM DUAL WHERE 1 &lt; '2'db<>fiddle试试。 谢谢,如果在 Spring Data JPA 中发生这种情况,任何指向此转换的文档 【参考方案1】:

这种行为是not documented。 查看the openJPA source code for Expressions.GreaterThan,更具体地说是toKernelExpression,

@Override
org.apache.openjpa.kernel.exps.Expression toKernelExpression(ExpressionFactory factory, CriteriaQueryImpl<?> q)
  Value val1 = Expressions.toValue(e1, factory, q);
  Value val2 = Expressions.toValue(e2, factory, q);
  Expressions.setImplicitTypes(val1, val2, e1.getJavaType(), q);
  return factory.greaterThan(val1, val2);

JPA 使用第一个表达式的类型来构建查询。 这种行为看起来是一个意外的功能,而不是有意的实现。你应该依赖这个并且应该明确地转换变量。您还可以使用MetaModel 在尝试将苹果与橙子进行比较时出现编译器错误。

【讨论】:

以上是关于Spring JPA 标准构建器大于:我可以传递字符串值以比较数据库中的数字类型吗的主要内容,如果未能解决你的问题,请参考以下文章

如何为以下语句编写标准构建器 API JPA 查询

构建RESTful服务(使用Spring Data JPA)

Spring JPA - 找不到实体管理器工厂,为啥?

Spring Data JPA 中的动态查询

Spring Boot中的JPA @query中没有传递参数[重复]

关闭应用程序后删除 Spring JPA 数据