9

I am trying to return an entity with a column that has the count of another table that is a one to many relation. I want to do this using hibernate criteria, not HQL.

select p.*, (select count(*) from child where child.parentid = p.id) as LEVELS
from parent p
2
  • Is your "where" clause supposed to be a "from"? Commented Feb 19, 2011 at 19:22
  • Thanks fixed that syntax error Commented Feb 19, 2011 at 19:28

4 Answers 4

5

If the parent entity also contains a list of children (bi-directional association), you can use criteria to return the count of children as follows:

    Criteria criteria = hibernateSessionHelper.getSessionFactory().getCurrentSession().createCriteria(Parent.class);

    ProjectionList projList = Projections.projectionList();
    projList.add(Projections.countDistinct("children.id"));
    projList.add(Property.forName("field1").group());
    projList.add(Property.forName("field2").group());
    projList.add(Property.forName("field3").group());
    .
    .
    .
    criteria.createAlias("children", "children", CriteriaSpecification.LEFT_JOIN);

    criteria.setProjection(projList);

    List<Object[]> results = crit.list();
Sign up to request clarification or add additional context in comments.

Comments

4

Got it to work doing this. Not very dynamic but it will work.

    @Basic
    @Column(name = "LEVEL")
    @Formula(value="(SELECT count(*) FROM BadgeLevels bl WHERE bl.badgeid = this_.id)")
        public long getLevel() {
        return level;
    }

Comments

0

Define an object field mapping like below. Then when you query your Parent objects, each object should have a field of type list called children that you can call size on.

<class name="Person">
    <id name="id" column="id">
        <generator class="native"/>
    </id>
    <set name="children">
        <key column="parentId" 
            not-null="true"/>
        <one-to-many class="Child"/>
    </set>
</class>

<class name="Child">
    <id name="id" column="childId">
        <generator class="native"/>
    </id>
</class>

1 Comment

I am returning a list of parents, and I don't want to return all the join childs of that object. I just want the count of the children with the parent columns.
0

You might be able to do it by some kind of projection.

See the tutorial on Hibernate projections. You are probably interested in the sqlProjection method in the Projections class for the sub-query.

List results = session.createCriteria(Parent.class, "p") 
    .setProjection(Projections.projectionList()
        .add(Projections.property("field1"))
        .add(Projections.property("field2"))
        .add(Projections.property("field3"))
        .add(Projections.sqlProjection("select count(*) from child where child.parentid = p.id"), new String[] {"LEVELS"}, new Type[] {Hibernate.INTEGER})
    ).list();

7 Comments

I am going to try that but is there anyway not to use raw sql, and use a detached query somehow?
The tricky part seems to be that, your count depends on another relation. If you use the Hibernate Association mappings, then you can map a list of Child objects and just use the Java size method.
See my other answer for the associations method.
That original project gave me select * from ( select select count(*) from badgelevels bl where bl.badgeid = b.id from CISCO.BADGES this_ where this_.ACTIVE=? ) where rownum <= ?
How can I return the rest of the columns from Parent.class with the count? Am I missing a projection?
|

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.