简体   繁体   English

获取集合计数而不是JPA Criteria API中的集合?

[英]Get collection count instead of the collection in JPA Criteria API?

Lets say I have an entity: 可以说我有一个实体:

@Entity
public class Person {

    @Id
    @GeneratedValue
    private Long id;

    @ManyToMany(fetch = FetchType.LAZY)
    private List<Role> roles;

    @ManyToMany(fetch = FetchType.LAZY)
    private List<Permission> permissions;
    // etc
    // other fields here
}

I want a to build a query using the Criteria API that filters these users and shows a list of people and among other info from the entity - how many roles does a person have. 我想要一个使用Criteria API构建查询,该查询可过滤这些用户并显示人员列表以及该实体的其他信息-一个人有多少个角色。

CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Person> query = builder.createQuery(Person.class);
Root<Person> personRoot = query.from(Person.class);
// predicates here

However, this limits me to returning only a list of Person entities. 但是,这将我限制为仅返回一个Person实体列表。 I can always add a @Transient field to the entity, but this seems ugly since I might have many different queries and might end up with many such fields. 我总是可以向实体添加@Transient字段,但这似乎很丑陋,因为我可能有很多不同的查询,并且最终可能会有很多这样的字段。

On the other hand - I cant use HQL and write the query since I want complex filtering and I would have to deal with appending and removing things from the HQL query. 另一方面-我不能使用HQL并编写查询,因为我要进行复杂的过滤,因此必须处理从HQL查询中添加和删除内容的问题。

My question, besides the one in the title of this post is this: how do I query the database using the Criteria API and return a non-entity (in case I want to filter the Person table but return only the number of roles, permissions, etc) and how do I do it for something very close to the actual entity (like the example with the role counter instead of the roles collection)? 我的问题,除了本文标题中的问题之外,是这样的:我如何使用Criteria API查询数据库并返回一个非实体(以防我要过滤Person表但仅返回角色数量,权限等),以及如何针对非常接近实际实体的东西(例如使用角色计数器而不是角色集合的示例)进行处理?

UPDATE Using Hibernate's projections I came up with this. 更新使用Hibernate的预测,我想到了这一点。 But still don't know that to write in TODO . 但是仍然不知道用TODO编写。 Projections.count doesn't work since it excpects some kind of grouping, and I don't seem to be able to find any examples in the Hibernate documentation. Projections.count无法正常工作,因为它需要某种分组方式,而且我似乎无法在Hibernate文档中找到任何示例。

Criteria cr = session.createCriteria(Person.class);

if (id != null) {
    cr.add(Restrictions.eq("id", id));
}

ProjectionList projectionList = Projections.projectionList();
projectionList.add(Projections.property("id"), "id");
projectionList.add(TODO, "rolesCount");

how do I do it for something very close to the actual entity (like the example with the role counter instead of the roles collection 我该如何针对非常接近实际实体的事物执行此操作(例如使用角色计数器而不是角色集合的示例

You could make these values properties of your User entity by various means, for example using a Hibernate @Forumula property. 您可以通过多种方式(例如,使用Hibernate @Forumula属性)为User实体设置这些value属性。 This will issue an inline subquery on Entity load to get the count without touching the collection. 这将在实体加载时发出内联子查询,以在不触及集合的情况下获得计数。

@Formula("select count(*) from roles where user_id = ?")
private int numberOfRoles;

Another (JPA compliant) option is to handle these calculated fields by creating a view at the database level and the mapping this to your User: 另一个(符合JPA的)选项是通过在数据库级别创建一个视图并将其映射到您的用户来处理这些计算出的字段:

eg 例如

@OneToOne
private UserData userData; //entity mapped to your view (works just like a table)

....

public int getNumberOfRoles(){
   return userData.getRoleCOunt();

or 要么

by using @SecondaryTable to join this User data. 通过使用@SecondaryTable联接此用户数据。

CriteriaQuery<Long> query = entityManager.getCriteriaBuilder().get().createQuery(Long.class);
query.select(builder.get().countDistinct(root));

works for me:) 为我工作:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM