hibernate怎么使用集合过滤?-问答-阿里云开发者社区-阿里云

开发者社区> 问答> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

hibernate怎么使用集合过滤?

在dao中有一个findAll方法,这个方法返回一个List集合,我想在这个返回的list的集合上运用hibernate的集合过滤功能,比如我想把这个集合中的所有对象的某个属性值小于3的过滤掉,其余的留在这个集合中返回给调用者,我的代码是这样写的:

dao 中的方法如下:

@SuppressWarnings("rawtypes")
    public List findAll() {
        Log.debug("finding all AdvanceQuery instances");
        try {
            Session session = this.getSession();
            String queryString = "from AdvanceQuery  a where a.frontNum = 0 order by a.cliCount desc";
            // String newQueryString =
            // PvgDataRoleUtil.querySqlFilter(queryString);
            System.out.println(queryString);
            Query queryObject = session.createQuery(queryString);
            return queryObject.list();
        } catch (RuntimeException re) {
            Log.error("find all failed", re);
            throw re;
        }
  
    }

测试方法如下:

public static void main(String[] args){
            AdvanceQueryDao advanceQueryDao = new AdvanceQueryDao();
            AdvanceQuery advanceQuery = new AdvanceQuery();
            List<AdvanceQuery> list = advanceQueryDao.findAll();
            for(AdvanceQuery advanceQuery2 :list){
                System.out.println(advanceQuery2.getCliCount());
            }
            Session session = HibernateUtil.getSession();
            Query query = session.createFilter(list,"where this.cliCount<3");
            List list1=query.list();
            for(int i = 0 ;i <list1.size();i++){
                AdvanceQuery advanceQuery2 = (AdvanceQuery)list1.get(i);
                System.out.println(advanceQuery2.getCliCount());
            }
      
    }

上述代码中的createFilter中的过滤条件其实是动态添加的,是不确定的,这只是一个例子,然后我运行代码时说这个集合没有被引用,怎么回事?

Hibernate: select advanceque0_.ID as ID1_11_, advanceque0_.FRONTNUM as FRONTNUM2_11_, advanceque0_.CLICOUNT as CLICOUNT3_11_, advanceque0_.TEMPLATENAME as TEMPLATENAME4_11_, advanceque0_.QUERYCLASSES as QUERYCLASSES5_11_, advanceque0_.LASQUERY as LASQUERY6_11_, advanceque0_.CLASSALIAS as CLASSALIAS7_11_, advanceque0_.DIAPLAIEDPRO as DIAPLAIEDPRO8_11_, advanceque0_.TEMLGROUP as TEMLGROUP9_11_, advanceque0_.NOTE as NOTE10_11_, advanceque0_.CREATEID as CREATEID11_11_, advanceque0_.LASTMODIFYID as LASTMODIFYID12_11_, advanceque0_.LASTMODIFYTIME as LASTMODIFYTIME13_11_, advanceque0_.CREATETIME as CREATETIME14_11_, advanceque0_.USERID as USERID15_11_ from ZCPLT_ADVANCEQUERY advanceque0_ where advanceque0_.FRONTNUM=0 order by advanceque0_.CLICOUNT desc
Exception in thread "main" org.hibernate.QueryException: The collection was unreferenced
    at org.hibernate.internal.SessionImpl.getFilterQueryPlan(SessionImpl.java:1526)
    at org.hibernate.internal.SessionImpl.createFilter(SessionImpl.java:1357)
    at zuccess.zcplt.basic.privilege.view.TestUtil.main(TestUtil.java:25)

我觉得可能是由于集合中的对象么有被持久化的原因,可是怎么给这个list中的对象持久化?

展开
收起
爵霸 2016-03-04 10:56:33 2171 0
1 条回答
写回答
取消 提交回答
  • 爵霸

    你这个需求我之前恰好做过类似的

    先要有个表存权限有关的数据 并在用户登陆后缓存起来

    然后所有的查询默认把当前登陆用户的权限数据放到查询里去(可以配置不带权限 该功能是一个隐式的操作 类似Filter)

    这里就会出现你说的这个问题 如果不对产生的SQL进行解析,那么很有可能被别名干扰 而且达不到最大效率

    然后还有个问题是列对应的问题 也就是哪些列匹配哪些列 这个也需要定义

    我后来的处理方式是

    1.争取所有表的字段进行统一 尽量避免同一个属性 多个命名的情况 如果出现则需要显示配置一下

    2.拿到所有需要过滤的表与列的信息(多种设置 默认不启用 一般配置为先全开 再去关掉不需要的)

    3.对查询SQL进行解析 这里有个重点 不允许内嵌SQL的列用别名 但是允许表别名(不然解析器写起来就麻烦了 为了达到效率最高化 最好是预处理我用的是MyBatis) 然后在表后面追加查询 默认放最里面

    2019-07-17 18:51:56
    赞同 展开评论 打赏
问答排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载