Reputation: 617
I have Laboratories with a collection of states, here are my simplified Classes:
LabState {
private Integer id;
private State state;
private Date date;
private String comments;
}
State{
private Integer id;
private String name;
}
Lab{
private Integer id;
private List<LabState> states = new ArrayList<LabState>();
private Date date;
private String name
}
I want to get via Hibernate Criteria the Last State from a specific laboratory. in mySql this work fine:
SELECT ls.* FROM labs_states les INNER JOIN
( SELECT idLab, idLabState, MAX(date) AS lastDate FROM labs_states GROUP BY idLab)
groupedLabs ON les.idLab = groupedLabs.idLab AND les.date = groupedLabs.lastDate
Edit: SearchMethod:
public List<Labs> search(LabSearch labSearch) {
SessionFactory sessionFactory = hibernateTemplate.getSessionFactory();
Session session = sessionFactory.openSession();
Criteria criteria = session.createCriteria(Lab.class);
criteria.add(Restrictions.like("name", "%" + labSearch.getName() + "%"));
if(labSearch.getState() != null){
criteria.createCriteria("states").add(Restrictions.eq("state", labSearch.getState())).addOrder(Order.asc("date")).list().get(0);
return (List<Lab>) criteria.list();
}
I don't nkow how to do this with Criteria, or if there is any other way to do
thanks
Upvotes: 1
Views: 6966
Reputation: 30813
to get the last state of the given lab
Criteria criteria = session.createCriteria(Lab.class)
.add(Restrictions.like("name", "%" + labSearch.getName() + "%"));
.createAlias("states", "labstate")
.createAlias("labstate", "state")
.addOrder(Order.desc("date"))
.setProjection(Projections.list()
.add(Projections.property("labstate.id"), "id")
.add(Projections.property("labstate.date"), "date")
.add(Projections.property("labstate.comments"), "comments")
.add(Projections.property("state.name"), "state"))
.setResultTransformer(Transformers.aliasToBean<LabstateDto>())
.setMaxResults(1);
return (List<LabstateDto>)criteria.list();
if you want more than one lab with its last state returned you'll need another query which is not that easy because you have the backreference from Labstate to Lab ony in db and not in class.
Update: in response to your comment an alternative query
Criteria criteria = session.createCriteria(Lab.class, "lab")
.add(Restrictions.like("name", "%" + labSearch.getName() + "%"));
.createAlias("states", "labstate")
.add(Subqueries.proptertyEq("labstate.Id", DetachedCriteria.for(Lab.class)
.add(Restrictions.propertyEq("id", "lab.id"));
.createAlias("states", "lstate")
.createAlias("labstate.state", "state")
.add(Restrictions.eq("name", state));
.addOrder(Order.desc("labstate.date"))
.setProjection(Projection.property("labstate.Id"))
.setMaxResults(1)
);
return (List<Lab>)criteria.list();
Upvotes: 1