【问题标题】:Get collection count instead of the collection in JPA Criteria API?获取集合计数而不是 JPA Criteria API 中的集合?
【发布时间】:2013-12-02 05:30:27
【问题描述】:

假设我有一个实体:

@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
}

我希望使用 Criteria API 构建一个查询,该 API 过滤这些用户并显示人员列表以及来自实体的其他信息 - 一个人有多少角色。

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

但是,这限制了我只返回Person 实体的列表。我总是可以在实体中添加一个@Transient 字段,但这看起来很难看,因为我可能有很多不同的查询,并且最终可能会有很多这样的字段。

另一方面 - 我不能使用 HQL 并编写查询,因为我需要复杂的过滤,而且我必须处理从 HQL 查询中添加和删除内容。

我的问题,除了这篇文章的标题是这样的:我如何使用 Criteria API 查询数据库并返回一个非实体(如果我想过滤 Person 表但只返回数量角色、权限等)以及如何为非常接近实际实体的内容执行此操作(例如使用角色计数器而不是角色集合的示例)?

更新 使用 Hibernate 的预测我想出了这个。但还是不知道写TODOProjections.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");

【问题讨论】:

标签: java hibernate jpa hql criteria


【解决方案1】:
CriteriaQuery<Long> query = entityManager.getCriteriaBuilder().get().createQuery(Long.class);
query.select(builder.get().countDistinct(root));

为我工作:)

【讨论】:

    【解决方案2】:

    对于非常接近实际实体的东西(例如 使用角色计数器而不是角色集合的示例

    您可以通过各种方式为您的用户实体创建这些值属性,例如使用 Hibernate @Forumula 属性。这将在实体加载时发出一个内联子查询,以在不触及集合的情况下获取计数。

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

    另一个(JPA 兼容)选项是通过在数据库级别创建视图并将其映射到您的用户来处理这些计算字段:

    例如

    @OneToOne
    private UserData userData; //entity mapped to your view (works just like a table)
    
    ....
    
    public int getNumberOfRoles(){
       return userData.getRoleCOunt();
    

    通过使用@SecondaryTable 加入此用户数据。

    【讨论】:

    • 这些都是变通方法。我正在寻找一种通用的符合 JPA 标准的方法来在 Criteria API 的帮助下实现这些查询。另外,非实体返回查询呢?
    • 好吧,如果这就是您要寻找的全部内容,我想投影和构造函数表达式就是您所追求的。
    猜你喜欢
    • 2012-11-12
    • 1970-01-01
    • 2016-06-23
    • 1970-01-01
    • 2018-01-10
    • 1970-01-01
    • 2020-11-16
    • 2014-01-27
    • 1970-01-01
    相关资源
    最近更新 更多