今天做项目的过程中发现,多表查询的时候如果使用hibernate的DetachedCriteria离线查询方式的时候,

在多表关联的时候我们需要使用别名的方式去实现。

但是代码运行的过程中抛出了下面的异常:

之前出现异常的代码:

    public String pageQuery() throws Exception {
DetachedCriteria dc = pageBean.getDetachedCriteria();
//动态添加过滤条件
String addresskey = model.getAddresskey();
if(StringUtils.isNotBlank(addresskey)){
//添加过滤条件,根据地址关键字模糊查询
dc.add(Restrictions.like("addresskey", "%"+addresskey+"%"));
} Region region = model.getRegion();
if(region != null){
String province = region.getProvince();
String city = region.getCity();
String district = region.getDistrict();
dc.createAlias("region", "r"); //第一次运行不会出错,但是第二次运行就会报错,因为之前已经存在了和它一样的别名,页面又是通过ajax请求的,不会刷新                           
if(StringUtils.isNotBlank(province)){
//添加过滤条件,根据省份模糊查询-----多表关联查询,使用别名方式实现
//参数一:分区对象中关联的区域对象属性名称
//参数二:别名,可以任意
dc.add(Restrictions.like("r.province", "%"+province+"%"));
}
if(StringUtils.isNotBlank(city)){
//添加过滤条件,根据市模糊查询-----多表关联查询,使用别名方式实现
//参数一:分区对象中关联的区域对象属性名称
//参数二:别名,可以任意
dc.add(Restrictions.like("r.city", "%"+city+"%"));
}
if(StringUtils.isNotBlank(district)){
//添加过滤条件,根据区模糊查询-----多表关联查询,使用别名方式实现
//参数一:分区对象中关联的区域对象属性名称
//参数二:别名,可以任意
dc.add(Restrictions.like("r.district", "%"+district+"%"));
}
}
subareaService.pageQuery(pageBean);
this.java2Json(pageBean, new String[]{"currentPage","detachedCriteria","pageSize",
"decidedzone","subareas"});
return NONE;
}

通过查阅资料发现:用DetachedCriteria或者Criteria,使用CreateAlias时,如果第2个参数alias与之前添加的重复,则会报系统异常,

然而遗憾的是我们的DetachedCriteria和Criteria并没有提供排除这种重复的方法。

要想在不修改Hibernate代码的前提下,解决这个问题,我们可以使用JAVA的反射类解决该问题。

下面提供两个函数,用于判断path和alias是否已经添加。

  private boolean existAlias(Criteria c, String path, String alias) {
Iterator itm = ((CriteriaImpl) c).iterateSubcriteria();
while (itm.hasNext()) {
Subcriteria sub = (Subcriteria) itm.next();
if (alias.equals(sub.getAlias()) || path.equals(sub.getPath())) {
return true;
}
}
return false;
} private boolean existAlias(DetachedCriteria c, String path, String alias) {
Class clazz = c.getClass();
try {
Field field = clazz.getDeclaredField("criteria");
field.setAccessible(true);
CriteriaImpl ci;
ci = (CriteriaImpl) field.get(c);
return existAlias(ci, path, alias); } catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} return false;
}

然后在之前的代码中调用提供的方法,并做如下修改可以解决问题

public String pageQuery() throws Exception {
DetachedCriteria dc = pageBean.getDetachedCriteria();
//每一次分页查询的时候应该先清除之前的条件
// 动态添加过滤条件
String addresskey = model.getAddresskey();
if (StringUtils.isNotBlank(addresskey)) {
// 添加过滤条件,根据地址关键字模糊查询
dc.add(Restrictions.like("addresskey", "%" + addresskey + "%"));
} Region region = model.getRegion();
if (region != null) {
String province = region.getProvince();
String city = region.getCity();
String district = region.getDistrict(); //创建别名之前需要判断别名是否存在。
boolean existAlias = existAlias(dc,null,"r");
if(!existAlias){//不存在就创建
dc.createAlias("region", "r");
}
if (StringUtils.isNotBlank(province)) {
// 添加过滤条件,根据省份模糊查询-----多表关联查询,使用别名方式实现
// 参数一:分区对象中关联的区域对象属性名称
// 参数二:别名,可以任意
dc.add(Restrictions.like("r.province", "%" + province + "%"));
}
if (StringUtils.isNotBlank(city)) {
// 添加过滤条件,根据市模糊查询-----多表关联查询,使用别名方式实现
// 参数一:分区对象中关联的区域对象属性名称
// 参数二:别名,可以任意
dc.add(Restrictions.like("r.city", "%" + city + "%"));
}
if (StringUtils.isNotBlank(district)) {
// 添加过滤条件,根据区模糊查询-----多表关联查询,使用别名方式实现
// 参数一:分区对象中关联的区域对象属性名称
// 参数二:别名,可以任意
dc.add(Restrictions.like("r.district", "%" + district + "%"));
}
}
subareaService.pageQuery(pageBean);
this.java2Json(pageBean,
new String[] { "currentPage", "detachedCriteria", "pageSize", "decidedzone", "subareas" });
return NONE;
}

别名重复问题之后,我们还需要解决的问题就是:

如何清除hibernate的上次查询条件,如果不清除,将会导致上次的查询条件和下次的查询条件合并到了一起。

具体参见:http://www.cnblogs.com/jepson6669/p/8876920.html

org.hibernate.QueryException: duplicate alias: r hibernate别名重复问题解决的更多相关文章

  1. org.hibernate.QueryException: Unable to resolve path [SecWilldosetdate.name],xxxxxxxx...异常处理

    今天在写hql语句的时候出现了这个错误,然后一直运行到执行hql这儿就出错了.页面报500. 原hql如下: String hql = "from SecWilldosetdate wher ...

  2. nested exception is org.hibernate.QueryException: could not resolve property

    SSH框架出现了下面的错误: nested exception is org.hibernate.QueryException: could not resolve property 检查了hbm.x ...

  3. org.hibernate.QueryException: could not resolve property

    org.hibernate.QueryException: could not resolve property HibernateSQLXML  org.hibernate.QueryExcepti ...

  4. org.hibernate.MappingException: duplicate import异常

    在开发hibernate时,一起多谢ORM类和映射文件时,报出:org.hibernate.MappingException: duplicate import com.XXX异常 解决方案: 检查你 ...

  5. org.hibernate.QueryException: could not resolve property: address of:

    Hibernate: select count(*) as y0_ from test.course this_ org.hibernate.QueryException: could not res ...

  6. Caused by:org.hibernate.DuplicateMappingException:Duplicate class/entity/ mapping

    1.错误描述 java.lang.ExceptionInInitializerError Caused by:org.hibernate.InvalidMappingException:Could n ...

  7. weblogic 下异常 org.hibernate.QueryException: ClassNotFoundException: org.hibernate.hql.ast.HqlToken

    项目之前在 Tomcat 环境下一直都正常运行,今天应客户要求需要迁移到 webLogic 10.3.6 下, 部署后竟然抛出了 org.hibernate.QueryException: Class ...

  8. org.hibernate.QueryException: JPA-style positional param was not an integral ordinal; nested exception is java.lang.IllegalArgumentException: org.hibernate.QueryException: JPA-style positional param w

    org.hibernate.QueryException: JPA-style positional param was not an integral ordinal; nested excepti ...

  9. 解决org.hibernate.QueryException illegal attempt to dereference collection 异常错误

    今天做项目的时候,有两个实体:款式.品牌两者关系是多对多的关联关系,实现的功能是:通过选择款式,显示出该款式的所有品牌.HQL语句如下: 运行时出现这个异常错误:org.hibernate.Query ...

随机推荐

  1. .net Stream篇(五)

    MemoryStream 目录: 1 简单介绍一下MemoryStream 2 MemoryStream和FileStream的区别 3 通过部分源码深入了解下MemoryStream 4 分析Mem ...

  2. 关于hibernate的查询

    为什么建议hibernate查询全部字段 一般而言,要查询什么字段就查询什么字段,不要select * from表,但是在hibernate,我们其实可以不遵循这个规则,建议我们把所有属性都查询出来( ...

  3. window.document 对象

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. CentOS 进程操作

    ps -ef:查看所有进程, ps -ef |grap firewalld 查看与firewalld相关的进程 which :查看进程:which firewalld kill 进程id:杀掉进程 k ...

  5. javascript js函数重名后面的覆盖前面的

    js 函数重名后面的覆盖前面的   var x = 1;    var y = 0;    var z = 0;    function add(n) { return n = n + 1; }    ...

  6. storm集群快速搭建

    sudo mkdir /export/serverssudo chmod -R 777 /exportmkdir /export/servers tar -zxvf apache-storm-1.0. ...

  7. newman的常用命令使用总结

    前提:为了运行newman,你要确保系统中安装的Node.js版本是大于v6的. 命令常用选项: newman [optiions] -h:显示命令行帮助,包括选项列表和简单的使用案例. -v:显示当 ...

  8. day1学python Hello Python

    Hello Python 本人使用的是Pycharm编译器 ----------------------------------------------- 1.输出 2.赋值 3.‘’‘/“”“ 多行 ...

  9. kali linux之netcat

    网络工具中的瑞士军刀----体积小,功能强大 侦听模式/传输模式 telnet/获取banner信息 传输文本信息,文件,目录 加密传输文件,远程控制/木马,加密所有流量(来做远程控制是非常理想的选择 ...

  10. DOM操作技术之动态脚本与动态样式(兼容版)

    动态脚本 使用<script>元素可以向页面中插入Javascript代码,一种方式是通过其src特性包含外部文件,另一种方式就是用这个元素本身来包含代码. 而我们要说的动态脚本,指的是在 ...