多态JPA查询与CriteriaQuery中API [英] Polymorphic JPA query with CriteriaQuery API

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

问题描述

我有以下实体结构:

   +-----------+                +-------------+        
   |  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实体加盟,并
应用了predicates。然后,我用匹配的子查询predicates的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();

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

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