Hibernate Projections.min() 返回了多行结果

3

我正在尝试获取表中一列的最小值。这听起来很简单,但我遇到了问题(我正在使用MySql 5.1数据库)。

情况有点复杂。 我们有一个由两个类实现的接口。 这两个类中的每一个都是从另外三个类扩展而来的。 这三个扩展器中的每两个都有hibernate映射(基类也有映射)=> 所以我们有 接口I实现:

classA(mapped) 扩展自 classA1(mapped) , classA2(mapped) , classA3(not mapped) classB(mapped) 扩展自 classB1(mapped) , classB2(mapped) , classB3(not mapped)

这里是一个带有示例代码的问题:

Criteria c = getSession().createCriteria(samplesType)
    .setProjection(Projections.min("pollingTime"));
List resultList= c.list()`enter code here`;

执行.list()后,resultList中有三个值:第一个是null,第二个是null,第三个包含我要查找的正确最小值。
我曾经使用c.uniqueResult(),但它会“返回”

org.hibernate.NonUniqueResultException:查询未返回唯一结果:3

我还尝试使用Hibernate的
createQuery(select min(pollingTime) from tableName).list()

但结果仍然相同(两个空值和一个正确的结果)。

我也尝试添加预定义的ResultTransformer来从列表中删除空值,但失败了。

作为解决方法,我可以使用SQL查询获取所需的最小值:

createSQLQuery("SELECT MIN(pool_time) FROM tableName") 

目前来看,这是唯一的解决方案。

你有什么想法,为什么返回结果不正确吗?

祝好, Niki

3个回答

2

与其专注于从列表中删除null,我认为你应该找出它们来自哪里。我想知道,你是否有表行,其中该列的值为null?也许你应该尝试类似这样的方法:

    select min(r.pollingTime) from r : tableName where r.pollingTime != NULL

事实上,这是我直接使用MySQL查询浏览器检查的首要事项之一。该列中没有任何空值。考虑到此列不是唯一键,并且未设置为非空键,这是一个不错的观点。尼基编辑:我也同意找出为什么会得到空值比找到过滤结果的方法更好。 - user1228603
我也尝试了以下代码。String qryStr = "select min(tn.pollingTime) from " + tableName + " tn where tn.pollingTime != NULL"; List resultList = getSession().createQuery(qryStr).list();现在列表中的结果被反转了: minValue,null,null。看起来只要我使用Hibernate(查询、条件、投影等)来完成这个任务,它就会返回错误的结果。 - user1228603

1
我找到了返回null的原因。正如我所描述的,系统中存在一些继承关系。因此,在搜索基类表中的最小值时,Hibernate会尝试查找所有子类表的最小值。在我们的情况下,子类表为空,因此没有最小值,因此它找到了正确的值以及来自子类表的null值。
为解决这个问题,我在Hibernate映射文件中将多态性设置为显式:
<class name="class" table="TABLE" polymorphism="explicit">

以上代码禁用在搜索超类表时搜索指定表。

Niki


1
根据数据类型,整数和字符串的最小值可能不同。例如,如果将1、2、11作为整数,则11是最大值。但如果将它们作为字符串,则2是最大值。
验证列的数据类型是什么。

所有映射文件中的数据类型均为long。它包含以毫秒为单位存储在类和数据库中的时间(根据Hibernate映射中定义)。 - user1228603

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接