bunnyjesse112
bunnyjesse112

Reputation: 747

Hibernate: using criteria with collections (HashSet)

I have the following classes:

  public class Folder{
      private Set<Documents> documents;
      private Set<Clip> clips;
  }

  public class Clip{
      private Owner owner;
  }

I need to find list of nice documents in yellow folders that have owners of clips in those folders, whose names are like search string. Something like this (not working):

Criteria criteria = session.createCriteria(Document.class);

criteria.add(Restrictions.eq("isNice", 1));
criteria.createCriteria("folder").add(Restrictions.eq("isYellow", 1));
criteria.createCriteria("clips");
criteria.createCriteria("owner").add(Restrictions.like("name", search));

List documents = criteria.list();

How do i create criteria for HashSet? Or

edit. I've found this snippet of code:

    List cats = sess.createCriteria(Cat.class)
    .createCriteria("kittens", "kt")
        .add( Restrictions.eq("name", "F%") )
    .setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP)
    .list();
Iterator iter = cats.iterator();
while ( iter.hasNext() ) {
    Map map = (Map) iter.next();
    Cat cat = (Cat) map.get(Criteria.ROOT_ALIAS);
    Cat kitten = (Cat) map.get("kt");
}

but i cant understand what exactly it does. Whats resultTransformer?

Please, any advice or tip would help so much! Thanks!

Upvotes: 2

Views: 2898

Answers (1)

JB Nizet
JB Nizet

Reputation: 691785

Criteria criteria = session.createCriteria(Document.class, "document");
criteria.add(Restrictions.eq("document.nice", true));
criteria.createAlias("document.folder", "folder");
criteria.add(Restrictions.eq("folder.yellow", true));
criteria.add(Subqueries.exists(clipOwnerWithNameInFolder(name, "folder"));

private DetachedCriteria clipOwnerWithName(String searchedName, String aliasOfFolder) {
    DetachedCriteria c = DetachedCriteria.forClass(Clip.class, "clip");
    c.createAlias("clip.owner", "owner");
    c.createAlias("clip.folder", "clipFolder");
    c.add(Restrictions.propertyEq("clipFolder.id", aliasOfFolder + ".id");
    c.add(Restrictions.like("owner.name", searchedName);
    c.setProjection(Projections.id());
}

This needs the Clip/Folder association to be bidirectional (i.e. you need to have a folder field in Clip). If it's not the case, the detached criteria could be created like this:

private DetachedCriteria clipOwnerWithName(String searchedName, String aliasOfFolder) {
    DetachedCriteria c = DetachedCriteria.forClass(Folder.class, "clipFolder");
    c.createAlias("clipFolder.clips", "clip");
    c.createAlias("clip.owner", "owner");
    c.add(Restrictions.propertyEq("clipFolder.id", aliasOfFolder + ".id");
    c.add(Restrictions.like("owner.name", searchedName);
    c.setProjection(Projections.property("clip.id"));
}

Upvotes: 2

Related Questions