Hibernate Criteria:计算最近的条目,按属性分组
Hibernate Criteria: counting the most recent entries, grouped per attribute
这是一个我觉得很难解开的结。
我的要求是使用 Criteria
API.
我有一个Team
class定义如下:
@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
有一个 State
的列表,因为它在其生命周期中会经过不同的状态。所以State
class定义如下
@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;
}
}
现在,我想要计算 当前 处于 given 状态的团队数量。当前状态是具有最新 date
值的状态。
我尝试了以下语句,但没有成功。
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();
}
谁能提供一些帮助?谢谢。
好吧,据我所知,您在 Team
上缺少连接。但我会尝试它来自 Team
并加入你的 State
class。
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();
没有测试,因为我没有环境,希望它有效。
我在下面写下我找到的解决这个问题的方法。
首先,我必须检索 State
table 的视图,其中包含按团队分组的最新状态的行,然后我必须为 type
添加限制。这里的技巧是生成一个带有 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();
}
这是一个我觉得很难解开的结。
我的要求是使用 Criteria
API.
我有一个Team
class定义如下:
@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
有一个 State
的列表,因为它在其生命周期中会经过不同的状态。所以State
class定义如下
@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;
}
}
现在,我想要计算 当前 处于 given 状态的团队数量。当前状态是具有最新 date
值的状态。
我尝试了以下语句,但没有成功。
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();
}
谁能提供一些帮助?谢谢。
好吧,据我所知,您在 Team
上缺少连接。但我会尝试它来自 Team
并加入你的 State
class。
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();
没有测试,因为我没有环境,希望它有效。
我在下面写下我找到的解决这个问题的方法。
首先,我必须检索 State
table 的视图,其中包含按团队分组的最新状态的行,然后我必须为 type
添加限制。这里的技巧是生成一个带有 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();
}