使用 CriteriaQuery API 的多态 JPA 查询 [英] Polymorphic JPA query with CriteriaQuery API

查看:41
本文介绍了使用 CriteriaQuery API 的多态 JPA 查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下实体结构:

   +-----------+                +-------------+        
   |  User     | -------------> |    Role     |
   +-----------+                +-------------+
                                       ^
                                       |
                               +-------+---------+
                               |                 |
                        +-----------+      +-----------+           +------------+
                        |   Role1   |      |  Role2    |-------->  | SomeEntity |
                        +-----------+      +-----------+           +------------+

并且我想获取其 Role2 具有具有特定属性值的 SomeEntity 的所有用户的名称.我需要使用 JPA 标准 API 来执行此操作.

and I want to get the names of all User whose Role2 has a SomeEntity with a specific property value. I need to do this with the JPA criteria API.

到目前为止我所做的是:

What I did so far is:

CriteriaBuilder cb = ...
CriteriaQuery<String> query = cb.createQuery(String.class);
Root<User> user = query.from(User.class);
SetJoin<User, Role> userRolesJoin = user.join(User_.roles);

// As you can see the userRolesJoin is of type Role and a Role doesn't have
// an property someEntity. So how to "cast" the userRolesJoin into an 
// SetJoin<User, Role2>.

这里怎么做多态查询?有什么建议吗?

How to do the polymorphic query here? Any suggestions?

遗憾的是,JPA 标准 API 不如 Hibernate 的标准 API 直观.

Unfortunatly the JPA criteria API is not as intuitive as Hibernate's critera API.

推荐答案

使用子查询解决

我创建了一个基于 Role2 类型的子查询,将它与SomeEntity"实体连接起来,然后应用谓词.然后我使用与子查询谓词匹配的 Role2.ids 将子查询连接到主"查询.

Solved it using a subquery

I created a subquery based on the Role2 type, joined it with the "SomeEntity" entity and applied the predicates. Then I connected the subquery to the "main" query using the Role2.ids that match the subquery predicates.

CriteriaBuilder cb = ...
CriteriaQuery<String> query = cb.createQuery(String.class);
Root<User> user = query.from(User.class);
SetJoin<User, Role> userRolesJoin = user.join(User_.roles);
Path<String> roleIdPath = userRolesJoin.get(User_.id);

Subquery<String> subquery = query.subquery(String.class);
Root<Role2> role2Root = subquery.from(Role2.class);
Join<Role2, SomeEntity> someEntityJoin = role2Root.join(Role2_.someEntity);
Path<String> someEntityPropertyPath = someEntityJoin.get(SomeEntity_.aProperty);
Predicate someEntityPropertyPredicate = cb.equal(someEntityPropertyPath,
            "a property value");
subquery.select(role2Root.get(Role2_.id));
subquery.where(someEntityPropertyPredicate);

In<String> idInSubqueryIds = cb.in(roleIdPath).value(subquery);

query.select(user.get(User_.username));
query.where(idInSubqueryIds);

EntityManager entityManager = ...;
TypedQuery<String> query = entityManager.createQuery(query);
List<String> usernames = query.getResultList();

这篇关于使用 CriteriaQuery API 的多态 JPA 查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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