0

I am trying to write a complex query using criteria API. I could use some help with this.

I have 3 classes, Assets, AssetComponent and Tasks. The Task class has a 1 to M relationship with AssetComponent and AssetComponent has 1 to M relationship with Asset. I need to find all Assets (it should be unique list) that have some tasks associated with them (the task has a component and the component knows a assets it is connected).

This is what I have so far

public List<Asset> retrieveTask(Project project, boolean assigned) {

  DetachedCriteria subquery = DetachedCriteria.forClass(Task.class);

  subquery.add(Restrictions.eq("project", project));
  if (assigned) {
     subquery.add(Restrictions.isNotNull("assignedTo"));
  } else {
     subquery.add(Restrictions.isNull("assignedTo"));
  }

  subquery = subquery.createCriteria("component");
  subquery.add(Restrictions.isNotNull("asset"));

  Criteria criteria = super.createCriteria();
  criteria.add(Subqueries.in("id", subquery));

  return criteria.list();
}

The deataced query should return all of the tasks that have asset assigned to them and are a part of the give project. Now I need to see what are the unique assets for all of those tasks.

Thanks for helping me with this.

Cheers

1
  • are you required use a subquery with the super.createCritera(), are you responsible for the code behind super.createCriteria(), and can you show us the code behind that call? Commented May 24, 2012 at 17:33

1 Answer 1

1

A bit of a shot in the dark, but how does this work for you:

public List<Asset> retrieveTask(Project project, boolean assigned) {

    DetachedCriteria subquery = DetachedCriteria.forClass(Task.class);

    subquery.add(Restrictions.eq("project", project));
    DetachedCriteria assetCriteria = subquery
        .createCriteria("component")
        .createCriteria("asset").setProjection(Projections.groupProperty("id"));

    Criteria criteria = super.createCriteria();
    if(assigned) {
        criteria.add(Subqueries.propertyIn("id", subquery));
    }
    else {
        criteria.add(Subqueries.propertyNotIn("id", subquery));
    }
    return criteria.list();
}
Sign up to request clarification or add additional context in comments.

4 Comments

This works perfectly. The thing that confused me was that DetachedCriteria assetCriteria that you used is never used in the code, but its subquery is. Thanks for help and fast reply. One more thing if how do I modify this code if I just want to return the number that represents the size of the list (using count or something like that)
I have changed the last part of the return into return (Long) criteria.setProjection(Projections.rowCount()).uniqueResult(); is this ok?
If you only want a single result back. I believe Hibernate will throw an exception if you have <> 1 result. If you are looking for unique assets you can also use a Unique Results Tranformer: criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
yea I just want to get the single number back from the query and that is the size of the entities that match my query

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.