2013-01-18 65 views
2

我试着去学习和了解JPA标准。 到目前为止,我在SQL中非常有能力,并且在Hibernate Criteria和HQL中相当有能力。JPA标准析取

我试图做一个非常简单的选择与OR语句。

在普通的SQL我选择这个样子的:

SELECT * FROM CHANGED_LOG 
WHERE key1 = 52540 AND objectCode = 'Order' 
OR key1 = 48398 AND objectCode = 'Package' 

这给了我所有行上键1 = 52540和目标代码等于订单 也是所有行上键= 48398和目标代码等于包。 这正是我想要的。

所以试图用JPA标准,要做到这一点(这似乎格外复杂...),我最好的猜测,到目前为止一直是这个:

CriteriaBuilder builder = entityManager.getCriteriaBuilder(); 

    CriteriaQuery<ChangedLogBean> query = builder.createQuery(ChangedLogBean.class); 
    Root<ChangedLogBean> from = query.from(ChangedLogBean.class); 
    CriteriaQuery<ChangedLogBean> select = query.select(from); 

    Predicate orderChangedLogBeans = builder.conjunction(); 
    builder.and(orderChangedLogBeans, builder.equal(from.get("key1"), orderId)); 
    builder.and(orderChangedLogBeans, builder.equal(from.get("objectCode"), ChangedLogBean.ObjectType.OrderBean)); 

    Predicate packageChangedLogBeans = builder.conjunction(); 
    builder.and(packageChangedLogBeans, builder.equal(from.get("key1"), packageId)); 
    builder.and(packageChangedLogBeans, builder.equal(from.get("objectCode"), ChangedLogBean.ObjectType.PackageBean)); 

    Predicate orderOrPackage = builder.disjunction(); 
    orderOrPackage.getExpressions().add(orderChangedLogBeans); 
    orderOrPackage.getExpressions().add(packageChangedLogBeans); 

    query.where(orderOrPackage); 

    return entityManager.createQuery(select).getResultList(); 

哇。很多简单查询的行...但仍然,这从数据库返回给我每一行。

我在这里做错了什么?

感谢您的所有有用的答案:)

回答

4

在这种情况下,首先要做的是为了记录生成的查询配置JPA提供商。一个例子见this q/a

要回答你的问题,我不确定使用getExpressions(),所以我建议以下粗鲁的做法:

Predicate p1 = builder.equal(...); 
Predicate p2 = builder.equal(...); 
Predicate p3 = builder.equal(...); 
Predicate p4 = builder.equal(...); 

Predicate p5 = builder.and(p1, p2); 
Predicate p6 = builder.and(p3, p4); 

query.where(builder.or(p5, p6)); 

你的错误是这样的一行:

builder.and(orderChangedLogBeans, builder.equal(from.get("key1"), orderId)); 

将不会修改orderChangedLogBeans。你必须得到由CriteriaBuilder#and()而是返回的谓词:

orderChangedLogBeans = builder.and(orderChangedLogBeans, builder.equal(from.get("key1"), orderId)); 
+0

感谢。简化和美丽。奇迹般有效。 – user829237