Posted at

HibernateDaoSupportの中で left join を使う方法

More than 3 years have passed since last update.

Hibernate 3.2.5GA では DetachedCriteria に JOIN の種類を指定する方法がなく、createAlias() は強制的に INNER JOIN になってしまう。

DetachedCriteria d = DetachedCriteria.forClass(Like.class);

if (idUserLike != null) d = d.add(Restrictions.eq("idUserLike", idUserLike));
if (idSession != null) d = d.add(Restrictions.eq("idSession", idSession));
if (idContent != null) d = d.add(Restrictions.eq("idContent", idContent));
if (typeContent != null) d = d.add(Restrictions.eq("typeContent", typeContent));
if (dateTimeStart != null) d = d.add(Restrictions.ge("dateTimeModified", dateTimeStart));
if (dateTimeEnd != null) d = d.add(Restrictions.lt("dateTimeModified", dateTimeEnd));

d = d.createAlias("userLike", "usrLike")
.createAlias("userContent", "usrContent") // INNER_JOIN のため userContent が存在しない行が出てこない
.addOrder(isAscending ? Order.asc(nameColumnOrder) : Order.desc(nameColumnOrder));
List<Like> result = (List<Like>)this.getObjectsByCriteria(d, indexOffset, numLikes);

そのため LEFT JOIN などを使いたい場合は Criteria を使う必要があるが、HibernateDaoSupport の中からは DetachedCriteria しか使えないと長い間思い込んでいた。今回 Criteria を使う方法が判ったのでメモ。

List result = getHibernateTemplate().executeFind(new HibernateCallback() {

public Object doInHibernate(Session session) {
Criteria c = session.createCriteria(Like.class);
if (idUserLike != null) c = c.add(Restrictions.eq("idUserLike", idUserLike));
if (idSession != null) c = c.add(Restrictions.eq("idSession", idSession));
if (idContent != null) c = c.add(Restrictions.eq("idContent", idContent));
if (typeContent != null) c = c.add(Restrictions.eq("typeContent", typeContent));
if (dateTimeStart != null) c = c.add(Restrictions.ge("dateTimeModified", dateTimeStart));
if (dateTimeEnd != null) c = c.add(Restrictions.lt("dateTimeModified", dateTimeEnd));
c = c.createAlias("userLike", "usrLike", CriteriaSpecification.INNER_JOIN)
.createAlias("userContent", "usrContent", CriteriaSpecification.LEFT_JOIN)
.addOrder(isAscending ? Order.asc(nameColumnOrder) : Order.desc(nameColumnOrder))
.setFirstResult(indexOffset).setMaxResults(numLikes);

return c.list();
}
});

なお、Hibernate 3.2.6GA 以降の DetachedCriteria では createAlias() に joinTypeが指定できる模様。