我需要设置一个更复杂的休眠过滤器,该过滤器由可能缺少的多个参数组成。基本上,我希望我的过滤器注入类似:
shipmentIds in (...) AND cityIds in (....) AND countryIds in (....)
在某些情况下,我可能只有 shipmentIds ,而注入的查询只能是
shipmentIds in (...)
并且由于我的过滤器需要根据我可以提供的ID进行动态调整,因此我尝试执行以下操作,但失败了:
@FilterDefs({
@FilterDef(name = CUSTOM_FILTER,
parameters = { @ParamDef(name = CUSTOM_QUERY, type = "string")})
})
@Filters({
@Filter(name = CUSTOM_FILTER, condition = " :"+ CUSTOM_QUERY +" ")
})
public class MyClass { ... }
我的过滤器逻辑:
org.hibernate.Filter filter = entityManager.unwrap(Session.class).enableFilter(CUSTOM_FILTER);
//customQuery contains the condition that I need to inject
filter.setParameter(CUSTOM_QUERY, customQuery);
filter.validate();
我得到的例外是这个:
org.postgresql.util.PSQLException: ERROR: argument of AND must be type boolean, not type character varying_
我怀疑这是由于我的过滤器使用的 type =“ string” 造成的。那是使用来自休眠的StringType,它用逗号将查询换行:
return '\'' + value + '\'';
那么有没有一种方法可以动态地注入这样的查询,或者我应该为id之间的每个组合定义多个自定义过滤器?
答案 0 :(得分:0)
我终于设法找到了解决此问题的方法,因此我将在此处添加答案。
那么有没有一种方法可以动态地注入这样的查询,或者我应该为id之间的每个组合定义多个自定义过滤器?
这里的解决方案不是动态插入单个查询,因为它仍然不可行,而是定义多个过滤器,而不是为每个组合定义自定义过滤器,而是为每个过滤器定义简单过滤器。接下来,我们基本上激活我们需要的任何一个,这样,最终查询将具有可提供的ID子句。
代码看起来像这样:
public void applyFiltering() {
// ... rest of the code to retrieve the set of ids
createFilterFor(cityIds, CITY_FILTER, CITY_IDS_PARAM);
createFilterFor(countryIds, COUNTRY_FILTER, COUNTRY_IDS_PARAM);
createFilterFor(shipmentIds, SHIPMENT_FILTER, SHIPMENT_IDS_PARAM);
}
private void createFilterFor(final Set<Long> ids, final String filterName, final String paramName) {
if(CollectionUtils.isNotEmpty(ids)) {
org.hibernate.Filter filter = entityManager.unwrap(Session.class).enableFilter(filterName);
filter.setParameterList(paramName, ids);
filter.validate();
}
}
注意: CITY_FILTER,CITY_IDS_PARAM 等只是用于正确加载过滤器的普通唯一常量字符串。
过滤逻辑:
shipmentIds in (...) AND cityIds in (....) AND countryIds in (....)
使用上述方法,最终查询可能会遇到其他条件,例如
shipmentIds in (...) AND cityIds in (....)
或
@Action(LoadSummary)
LoadSummary({ patchState, dispatch }: StateContext<StateModel>, { id }: LoadSummary) {
this.detailService.getSummary(id).subscribe((response) => {
patchState({
summary: response?.data
});
// dispatch success action
dispatch(new LoadSummarySuccess());
});
}
或只是个人。