Wednesday, September 15, 2010

Hibernate: Parent and Children --> Retrieving Children using a Filter

Same classes as the previous post but this time to avoid an issue with lazy loading the children outside of a closed Hibernate session, load the parent and its children together in the DAO.

This is slightly more complicated as the data model class now has a status attribute (true || false). Either load all the data or only load the data that is active (If a parent is not active, it is not loaded so none of its children is loaded either).

Using the Criteria API, there doesn't seem to be a way to specify a join criteria on the children join.
You can do it easily using a query:
from Cat as cat
left join cat.kittens as kitten
with kitten.bodyWeight > 10.0
Hence the use of a filter when using the Criteria API. The filter either restricts the children to be active or just loads all of them.

@Repository
public class HibernatePropertyTypeDaoImpl extends BaseHibernateDao implements PropertyTypeDao {
  
  private static final String ACTIVE_WHERE_CLAUSE = "where active = true";
  
  private static Logger LOG = LoggerFactory.getLogger(HibernatePropertyTypeDaoImpl.class);

  @Override
  @SuppressWarnings("unchecked")
  public List getCommercialPropertyTypes(boolean onlyActive) {
    List commercialTypes = (List) getPropertyTypesWithoutChildren(CommercialPropertyType.class, onlyActive);
    for(CommercialPropertyType commercialType : commercialTypes) {
      getChildren(commercialType, onlyActive);
    }
    return commercialTypes;
  }
  
  @SuppressWarnings("unchecked")
  private List getPropertyTypesWithoutChildren(Class clazz, boolean onlyActive) {
    Criteria criteria = sessionFactory.getCurrentSession().createCriteria(clazz); 
    criteria.add(Restrictions.isNull("parent"));
    if (onlyActive) {
      criteria.add(Restrictions.eq("active", true));
    }
    criteria.addOrder(Order.asc("id"));
    return criteria.list();
  }

  @SuppressWarnings("unchecked")
  protected void getChildren(CommercialPropertyType type, boolean onlyActive) {
    List children = null;
    if (onlyActive) {
      children = sessionFactory.getCurrentSession()
                               .createFilter(type.getChildren(), ACTIVE_WHERE_CLAUSE)
                               .list();
    } else {
      children = sessionFactory.getCurrentSession()
                               .createFilter(type.getChildren(), "")
                               .list();
    }
    type.setChildren(children);
    LOG.debug("Set children:"+children);
  } 
}

No comments:

Post a Comment