在项目中使用HQL时的遇有多个类的嵌套比较发生的异常:
错误信息如下:
org.hibernate.hql.ast.InvalidWithClauseException: with-clause expressions did not reference from-clause element to which the with-clause was associated
错误原因:使用类之间的关联太深了,关联不到相关的对象
/**
* 分页查询 根据查询条件,得到符合条件的订单列表的集合(仅限预定员个人的操作)
*
* @param <T>
* @param vacationorderCondition
* @param paginater
* @return
*/
public <T> Paginater<T> searchPartVacationOrderList(final VacationOrderCondition vacationorderCondition, Paginater<T> paginater) {
Sorter sorter = paginater.getSorter();
if (sorter == null || sorter.isEmpty()) {
sorter = new Sorter().asc("p.createdTime");
}
LimitedList<T> limitedList = findByQuery(new QueryCreator() {
public Query createQuery(Session session) {
DynamicQuery dquery = new DynamicQuery(" select distinct v from VacationOrder v ");
// 机位未确定订单
if (VacationOrderQueryType.Flight_Unknow_order_list == vacationorderCondition.getQueryType()) {
dquery.append(" inner join v.flightOrders vf with vf.status !=" + VacationOrderConfirmStatus.CONFIRM.getCode());
// 酒店未知订单列表
} else if (VacationOrderQueryType.Hotel_unknow_order_list == vacationorderCondition.getQueryType()) {
dquery.append(" inner join v.hotelOrders vh with vh.status !=" + VacationOrderConfirmStatus.CONFIRM.getCode());
// 未读取传真的订单列表
} else if (VacationOrderQueryType.UnRead_fax_order_list == vacationorderCondition.getQueryType()) {
dquery.append(" inner join v.hotelOrders vh join vh.hotelOrder as h with h.orderStatus=" + OrderStatus.FAXED.getCode());
/***
上面深青色的代码如果采用下面蓝色的代码将发生上述异常,原因关联不到相关的对象。
dquery.append(" inner join v.hotelOrders .hotelOrder as h with h.orderStatus=" + OrderStatus.FAXED.getCode());
***/
// 可选项的订单列表
} else if (VacationOrderQueryType.Option_unconfirm_order_list == vacationorderCondition.getQueryType()) {
dquery.append(" inner join v.multipleOrders vm with vm.status !=" + VacationOrderConfirmStatus.NEW);
}
dquery.append(" where (1 = 1) ");
dquery.appendIfNotNull(" and v.id=:orderNo ", "orderNo", vacationorderCondition.getOrderNo());
dquery.appendIfNotEmpty(" and v.cityCode=:cityCode ", "cityCode", vacationorderCondition.getCityCode());
dquery.appendIfNotEmpty("and v.subscriber.name=:operatorName", "operatorName", vacationorderCondition.getOperatorName());
dquery.appendIfNotNull(" and v.orderPaymentType=:orderPaymentType", "orderPaymentType", vacationorderCondition.getOrderPaymentType());
dquery.appendIfNotNull(" and v.vacationType in (:vacationType)", "vacationType", vacationorderCondition.getVacationTypes());
dquery.appendIfNotNull(" and v.vacationcategory in (:vacationcategory)", "vacationcategory", vacationorderCondition
.getVacationCategorys());
dquery.appendIfNotNull(" and v.subscriberId=:subscriberId", "subscriberId", vacationorderCondition.getSubscriberId());
dquery.appendIfNotEmpty(" and v.productMgr=:productMgr", "productMgr", vacationorderCondition.getProductMgr());
// 构建其他的查询条件的信息
if (vacationorderCondition.getQueryType() != null) {
createDynamicQuery(vacationorderCondition.getQueryType(), dquery);
}
return dquery.build(session);
}
}, paginater.getLimit(), sorter);
return paginater.fromLimitedList(limitedList);
}
特别关注:
在HQL中使用With用于设置查询的限制条件,减少关联的信息。