Crinteria加入OR的make AND insetad [英] Crinteria Join make AND insetad of OR
问题描述
我的问题是我设置了cb.或者它设置了cb,.. cb是CriteriaBuilder 我的课是:
My problem is that wen i set cb.or it do cb and.. cb is CriteriaBuilder My class is :
public class User extends BaseEntity<User> {
public static final String CHILDREN_FIELD = "children";
public static final String PARENT_FIELD = "parent";
//Id column based in BaseEntity
OneToOne(fetch = LAZY)
JoinColumn(name = "parent_partner_id")
User parent;
OneToMany(mappedBy = "parent", fetch = LAZY,cascade = {})
private List<User> children;
我的标准代码是:
Root<User> root = query.from(User.class);
Join<User, User> userJoin = root.join(CHILDREN_FIELD, JoinType.LEFT);
userJoin.on(
cb.or(
cb.equal(userJoin.get(ID_FIELD), root.get("id")))
);
代码生成:
select
user0_.id as col_0_0_
from
user user0_
left outer join
user children2_
on user0_.id=children2_.parent_id
and ( <- i write OR in cb!! why it generates AND ?
children2_.id=user0_.id
)
我该如何解决?为什么我的代码会生成AND语句?
How can I resolve it? Why my code generates AND statement?
推荐答案
很抱歉告诉您,使用API标准今天不可能,我将告诉您其他选项:
I'm sorry to tell you that with API criteria it is not possible today, I will tell you about different options:
1.-使用本机查询
使用本地查询不是问题,因为您正在使用所有数据库管理器都支持的子句
The use of native query is not a problem since you are using clauses supported by all DB managers
List<User> result = em.createNativeQuery("select * from user p "+
"left outer join user p1 on p.id = p1.parent_id or p.id = p1.id",
"User.nativeConstructorMapping").getResultList();
在您的实体中
@SqlResultSetMappings({
@SqlResultSetMapping(name="User.nativeConstructorMapping",
classes = {
@ConstructorResult(
targetClass = Users.class,
columns = {
@ColumnResult(name = "id", type = Long.class),
@ColumnResult(name = "name", type = String.class)
[...]
})
})
})
....
public User(Long id, String name, [...]) {
super();
this.id= id;
this.name = name
[...]
}
2.-使用两个根,以防内部联接为您服务,而不是用左联接在where中添加on子句的条件
2.- Use two roots, in case inner join would serve you instead of left join adding the conditions of the on clause in the where
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<User> query = cb.createQuery(User.class);
Root<User> root1 = query.from(User.class);
Root<User> root2 = query.from(User.class);
query.where(cb.or(
cb.equal(root1.get(User_.id),root2.get(User_.parent).get(User_.id)),
cb.equal(root1.get(User_.id),root2.get(User_.id)))
);
正如我告诉您的那样,尽管不建议使用本机查询,因为它违反了JPA原则,但是在这种情况下,由于您不使用任何数据库的子句,这应该不是问题,但我会我会选择的选项.
As I was telling you, although it is not recommended to use native queries because it breaks with the JPA philosophy, in this case as you do not use the clauses of any DB it should not be a problem, I would be the option I would choose.
这篇关于Crinteria加入OR的make AND insetad的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!