Crinteria加入OR的make AND insetad [英] Crinteria Join make AND insetad of OR

查看:74
本文介绍了Crinteria加入OR的make AND insetad的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题是我设置了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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆