【发布时间】:2018-01-25 19:32:31
【问题描述】:
带有“in”表达式的 JPA 条件 API 转换为多个“OR”而不是“in”
例如
我的主要模特
public class Person {
...
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "department_id")
private Department department;
...
}
多对一关系
public class Department {
@Id
@Column(name="department_id")
private Integer departmentId;
@OneToMany(mappedBy="department")
private List<Person> person;
...
}
在persistence.xml中定义了这两个模型(注意:它没有指定任何db方言)
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="primary" transaction-type="JTA">
<jta-data-source>java:openejb/Resource/jdbc/myDS</jta-data-source>
<class>com.xyz.Person</class>
<class>com.xyz.Department</class>
...
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
<properties>
<property name="openjpa.Log" value="${open.jpa.log}" />
<property name="openjpa.ConnectionFactoryProperties" value="printParameters=true" />
<property name="openjpa.RuntimeUnenhancedClasses" value="unsupported" />
</properties>
</persistence-unit>
</persistence>
以下是使用 Criteria API 构建查询的代码:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Person> criteriaQuery = cb.createQuery(Person.class);
Root<Person> personRoot = criteriaQuery.from(Person.class);
criteriaQuery.select(personRoot);
List<Predicate> predicateList = new ArrayList<>();
predicateList.add(personRoot.get(Person_.department).get(Department_.departmentId).in(Arrays.asList(1, 2, 3)));
// Using list because I actually need to add multiple conditions
criteriaQuery.where(predicateList.toArray(new Predicate[0]));
TypedQuery<Person> searchQuery = em.createQuery(criteriaQuery);
searchQuery.getResultList();
这会以以下格式打印查询:
SELECT t0.person_id, ...
FROM person t0
WHERE ((t0.department_id = ? OR t0.department_id = ? OR t0.department_id = ?) AND t0.department_id IS NOT NULL)
但我应该得到的是
SELECT t0.person_id, ...
FROM person t0
WHERE t0.department_id IN (?, ?, ?)
环境:
- Tomee 7.0.3
- 嵌入式 OpenJPA
- Mariadb
更新:
我也尝试过如下添加mariadb方言,但没有帮助
<property name="openjpa.jdbc.DBDictionary" value="mariadb" />
【问题讨论】:
-
可能后端(方言)没有'in' ???。使用什么真实数据库?
-
它是 mariadb。 Mariadb 支持'in'
-
尝试将
java.sql.Array传递给in- 使用SQL"... in(?)"。 -
尝试将“(1,2,3)”指定为 PARAMETER,并在运行时提供 List 作为参数值。
-
在 SQL 中,一个表达式:
x IN (1, 2, 3)等同于x=1 or x=2 or x=3,它给出的结果完全相同。你为什么担心它?我个人不会关心它。