hibernate6 如何优雅的返回List<Map<String,Object>

我要封装一个基于hibernate6的 查询函数,大概的需求是这样的,传入一个hql语句,返回List<Map<String,Object>>,完成的函数如下:

public List<Map> findMap(String hql, Object... values) throws Exception {
        Query<Map> queryObject = getSession().createQuery(hql,Map.class);
        if (values != null) {
            for (int i = 1; i <= values.length; i++) {
                if (values[i-1].getClass().isArray()) {
                    Object[] pas = (Object[]) values[i-1];
                    queryObject.setParameterList(i, pas);
                } else {
                    queryObject.setParameter(i, values[i-1]);
                }
            }
        }
        queryObject.unwrap(Query.class).setTupleTransformer((tuple, aliases)->{
            Map<String, Object> map=new HashMap<>(); 
            map.put(aliases[0], tuple[0]);
            return map;
        });
        return queryObject.list();
    }

以上代码是可以运行的,但是两个警告:
1、Map is a raw type. References to generic type Map<K,V> should be parameterized
2、Type safety: The method setTupleTransformer(TupleTransformer) belongs to the raw type Query. References to generic type Query should be parameterized
请问在不使用注解 :@SuppressWarnings({ "rawtypes", "unchecked" })的情况下,如何优雅的消除这个警告
第一个警告是因为

Query<Map> queryObject = getSession().createQuery(hql,Map.class);

产生的,而下述代码也不完美

//hibernate6不建议使用这样的语句
Query<Map<String,Object>> queryObject = getSession().createQuery(hql);
//这样的代码编译出错
Query<Map<String,Object>> queryObject = getSession().createQuery(hql,Map.class);

第二个警告,个人估计也是因为queryObject.unwrap(Query.class)中的Query 没有指定类型导致的,毕竟原型是Query

queryObject.unwrap(Query.class).setTupleTransformer((tuple, aliases)->{
            Map<String, Object> map=new HashMap<>(); 
            map.put(aliases[0], tuple[0]);
            return map;
        });

参考GPT和自己的思路:

对于第一个警告,可以使用泛型来消除,将函数签名改为:

public List<Map<String, Object>> findMap(String hql, Object... values) throws Exception {

同时,需要将第2行的代码改为:

Query<Map<String, Object>> queryObject = getSession().createQuery(hql);

对于第二个警告,需要将第13行的代码改为:

queryObject.unwrap(org.hibernate.query.Query.class).setTupleTransformer((tuple, aliases)->{

使用完整的泛型类型,以及使用org.hibernate.query.Query代替原来的Query,可以消除警告。

如果将第2行的代码改为Query<Map<String,Object>> queryObject = getSession().createQuery(hql);,则不需要使用元素转换器了,不需要第13-17行的代码。直接返回queryObject.list()即可。

参考GPT和自己的思路:

针对第一个警告,可以在方法声明中使用泛型,将Map改为Map<String, Object>。修改后的代码如下:

public List<Map<String, Object>> findMap(String hql, Object... values) throws Exception {
    Query<Map<String, Object>> queryObject = getSession().createQuery(hql, Map.class);
    if (values != null) {
        for (int i = 1; i <= values.length; i++) {
            if (values[i-1].getClass().isArray()) {
                Object[] pas = (Object[]) values[i-1];
                queryObject.setParameterList(i, pas);
            } else {
                queryObject.setParameter(i, values[i-1]);
            }
        }
    }
    queryObject.unwrap(Query.class).setTupleTransformer((tuple, aliases) -> {
        Map<String, Object> map = new HashMap<>();
        map.put(aliases[0], tuple[0]);
        return map;
    });
    return queryObject.list();
}

针对第二个警告,可以在createQuery方法中指定泛型参数,避免使用原始类型。修改后的第二个问题代码如下:

Query<Map<String, Object>> queryObject = getSession().createQuery(hql, Map.class);

参考GPT和自己的思路:

对于第一个警告:Map is a raw type. References to generic type Map<K,V> should be parameterized。建议改为声明Map<String,Object>。

改动后的代码如下所示:

public List<Map<String,Object>> findMap(String hql, Object... values) throws Exception {
    Query<Map<String,Object>> queryObject = getSession().createQuery(hql,Map.class);
    if (values != null) {
        for (int i = 1; i <= values.length; i++) {
            if (values[i-1].getClass().isArray()) {
                Object[] pas = (Object[]) values[i-1];
                queryObject.setParameterList(i, pas);
            } else {
                queryObject.setParameter(i, values[i-1]);
            }
        }
    }
    queryObject.unwrap(Query.class).setTupleTransformer((tuple, aliases)->{
        Map<String, Object> map=new HashMap<>();
        map.put(aliases[0], tuple[0]);
        return map;
    });
    return queryObject.list();
}

对于第二个警告:Type safety: The method setTupleTransformer(TupleTransformer) belongs to the raw type Query. References to generic type Query should be parameterized。建议将setTupleTransformer的参数声明为TupleTransformer<Map<String, Object>>。

改动后的代码如下所示:

queryObject.unwrap(Query.class).setTupleTransformer((TupleTransformer<Map<String, Object>>) (tuple, aliases)->{
    Map<String, Object> map=new HashMap<>();
    map.put(aliases[0], tuple[0]);
    return map;
});

对于第二个问题,如果使用泛型声明,可以直接写为:Query<Map<String,Object>>。

这是参数类型的警告,要匹配一致。

我知道要保证类型一致啊,问题是我咋写 才能保证一致啊