4

JPA基準を学び、理解しようとしています。これまでのところ、私は SQL で非常に有能であり、Hibernate Criteria と HQL でかなり有能です。

OR ステートメントでかなり単純な選択をしようとしています。

プレーン SQL では、私の select は次のようになります。

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

これにより、key1 = 52540 で objectCode が Order に等しいすべての行と、key = 48398 で objectCode が Package に等しいすべての行が得られます。これはまさに私が欲しいものです。

したがって、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();

わお。単純なクエリには多くの行があります...それでも、これはDBからすべての行を返します。

ここで何が間違っていますか?

役に立つ回答をありがとう:)

4

1 に答える 1

6

このような場合に最初に行うことは、生成されたクエリをログに記録するために JPA プロバイダーを構成することです。例については、この 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()によって返される Predicate を取得する必要があります。

orderChangedLogBeans = builder.and(orderChangedLogBeans, builder.equal(from.get("key1"), orderId));
于 2013-01-18T11:23:13.027 に答える