Search code examples
hibernatejspspring-mvchibernate-criteria

Hibernate criteria query to display children


I am trying to develop a currently very simple web application using Hibernate for the data portion. Basically, I am attempting to get a table with a row for each category. In one cell for each row, I want to display the KPIs for that category. To do that, I am attempting to use a criteria object. The immediate problem is that nothing I can do results in that second query even firing.

Here are the hopefully relevant bits from my code. I've tried all sorts of things, this is what I've currently got.

Category.java

    @Entity
@Table(name="category")
public class Category {
    @Id
    @Column(name="category_id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id;

    @Column(name="category_name")
    private String categoryName;

    @Transient
    private Kpi[] kpis;
...
    public Kpi[] getKpis() {
        return this.kpis;
    }
}

CategoryDAO

public interface CategoryDAO {

    public List<Category> listCategories();
    public Category getCategoryById(int id);
    public List<Kpi> getKpisForCategory(int cat);
}

CategoryDAOImpl

public class CategoryDAOImpl implements CategoryDAO {
    private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sf){
        this.sessionFactory = sf;
    }

...
    @SuppressWarnings("unchecked")
    @Override
    public List<Kpi> getKpisForCategory(int cat) {
        Session session = this.sessionFactory.getCurrentSession();
        Criteria criteria = session.createCriteria(Kpi.class).add(Restrictions.eq("category_id",cat));
        return criteria.list();
    }
}

CategoryServiceImpl

 @Service
    public class CategoryServiceImpl implements CategoryService {

        private CategoryDAO categoryDAO;

        public void setCategoryDAO(CategoryDAO dao) {
            this.categoryDAO = dao;
        }
...    
        @Override
        public List<Kpi> listKpisForCategory(int cat) {
            System.out.println("in service method");
            return this.categoryDAO.getKpisForCategory(cat);
        }
    }

jsp

<c:if test="${!empty listCategories}">
    <table class="tg">
        <tr>
            <th width="80">Category ID</th>
            <th width="120">Category Name</th>
        </tr>
        <c:forEach items="${listCategories}" var="category">
        <tr>
            <td>${category.id}</td>
            <td>${category.categoryName}</td>
            <td>
                <table class="tg">
                    <tr>
                        <th>KPI Name</th>
                    </tr>
                    <tr>

                    <c:forEach items="${category.kpis }" var="kpi">
                        <td>${category.id}
                        <td>${kpi.kpiName }</td>
                    </c:forEach>
                    </tr>
                </table>
            </td>
        </tr>
        </c:forEach>
    </table>    
</c:if>

No matter what I do, I end up with the nested table being empty, and the child query never fires (which I can tell due to my high tech logging!). What am I missing? (sorry for the wall of text...)


Solution

  • Thanks to @Naros's comment, I was able to get it working. In the CategoryDAOImpl class, I added some code to the listCategories() method to populate the Kpi list in the Category object:

    @SuppressWarnings("unchecked")
        @Override
        public List<Category> listCategories() {
            System.out.println("dao impl list categories");
            Session session = this.sessionFactory.getCurrentSession();
            List<Category> categoryList = session.createQuery("from Category").list();
    
            for (Category c : categoryList) {
                List<Kpi> kpiList = getKpisForCategory(c.getId());
                c.setKpis(kpiList);
            }
            return categoryList;
        }