简体   繁体   English

Hibernate Criteria:计算最新的条目,按属性分组

[英]Hibernate Criteria: counting the most recent entries, grouped per attribute

This is a knot I find quite hard to untie. 这是一个我很难解开的结。

My requirement is to use the Criteria API. 我的要求是使用Criteria API。

I have a Team class defined as follows: 我有一个Team类定义如下:

@Entity
@Table(name="TEAMS")
public class Team{

    private Set<State> states = new HashSet<State>();

    @OneToMany(cascade=CascadeType.ALL, orphanRemoval=true, mappedBy="team")
    public Set<State> getStates() {
        return states;
    }
}

A Team has a list of State s because it transits through different states during its lifecycle. Team有一个State列表,因为它在其生命周期中通过不同的状态。 So the State class is defined as follows. 所以State类定义如下。

@Entity
@Table(name="STATES")
public class State{

    private Team team;
    private StateType type;
    private Date date;

    @ManyToOne
    @JoinColumn(name="TEAM_ID")
    public Team getTeam() {
        return team;
    }

    @Column(name="STATE_TYPE")
    public StateType getType() {
        return type;
    }

    @Temporal(TemporalType.DATE)
    @Column(name="DATE")
    public Date getDate() {
        return date;
    }
}

Now, what I want is to count the number of teams which are currently in a given state. 现在,我想要的是计算当前处于给定状态的团队数量。 The current state is the one with the most recent date value. 当前状态是具有最新date值的状态。

I tried with the following statement, but with no luck. 我尝试了以下声明,但没有运气。

public Long getStateTypeNumber(StateType type)
{
    Session session = sessionFactory.getCurrentSession();
    Criteria criteria = session.createCriteria(State.class);
    criteria.add(Restrictions.eq("type", type));
    criteria.addOrder(Order.desc("date"));
    criteria.setProjection(Projections.distinct(Projections.property("team")));
    criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
    criteria.setProjection(Projections.rowCount());
    return (Long) criteria.uniqueResult();
}

can anyone provide some help? 谁能提供一些帮助? Thanks. 谢谢。

Well from what I see you're missing a join on your Team . 好吧,从我看到你错过了你的Team加入。 But I would try it coming from Team and joining your State class. 但我会尝试从Team加入你的State班级。

Session session = sessionFactory.getCurrentSession();
Criteria criteria = session.createCriteria(Team.class);
criteria.createAlias("states", state);
criteria.add(Restrictions.eq("state.type", type));
criteria.setProjection(Projections.rowCount());
(Long) criteria.uniqueResult();

Didn't test it because I don't have the enviroment with me, hope it works. 没有测试它,因为我没有环境,希望它有效。

I write in the following the solution I found for this problem. 我在下面写了我找到的解决这个问题的方法。 First, I have to retrieve a view of my State table containing the rows of the most recent states grouped by team, then I have to add restrictions for the type . 首先,我必须检索包含按团队分组的最新状态行的State表的视图,然后我必须为该type添加限制。 The trick here is to generate a subquery with a DetachedCriteria to be used inside a Criteria (thanks to @Jan for pointing it out). 这里的技巧是生成一个带有DetachedCriteria的子查询,以便在Criteria (感谢@Jan指出它)。

public Long getStateTypeNumber(StateType type)
{   
    DetachedCriteria maxDateQuery = DetachedCriteria.forClass(State.class);     
    maxDateQuery.setProjection(Projections.projectionList().
            add(Projections.max("date")).
            add(Projections.groupProperty("team")));

    Session session = sessionFactory.getCurrentSession();
    Criteria criteria = session.createCriteria(State.class);
    criteria.add(Subqueries.propertiesIn(new String[] {"date", "team"}, maxDateQuery));
    criteria.add(Restrictions.eq("type", type));
    criteria.setProjection(Projections.rowCount());
    return (Long) criteria.uniqueResult();      
}

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

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