How to return max of identity column via Hibernate accessing Oracle DB?
由于HQL(createQuery)似乎不支持标量查询,因此我通过createSQLQuery使用了原始查询:
1 2 3 4 5 6 7 8 9
| session. beginTransaction();
Query query = session. createSQLQuery("select nvl(max(id), 0) + 1 from empty_table_for_now");
session. getTransaction(). commit();
List listL = query. list();
Iterator iterator = listL. iterator();
while (iterator. hasNext()) {
LOG. info("Infinite loop. This is disgusting!");
} |
查询本身不会失败,但它似乎返回一个包含无限数量结果的列表? 这没有意义......任何想法为什么我得到这个?
更好的是,是否有更好,更优雅的方式来获得预期的标量,而不必混淆维护我的代码的人与"列表"(应该总是包含一个元素)?
-
您不应该使用select max(..)来生成唯一值。它不正确或不会缩放。请改用序列
-
@a_horse_with_no_name谢谢。你是对的,但在我的特殊情况下,序列是一种矫枉过正(也有自己的问题)。我现在坚持使用max(),因为我将始终只有一个进程创建和/或更新此表。
-
max()方法是一个更大的"矫枉过正"。特别是在大型表上,查询将非常慢,而使用序列要快得多。
-
你再一次是对的,但在我的特殊情况下,表现不是问题。 OTOH,序列往往会在DBA不与开发人员交谈并且尾巴摇尾巴的组织中失去同步(或最大化)。 ;)然后,我刚看到@ PRK的答案,所以如果我能让Hibernate为我处理这个问题,我一定会采取正确的路线。
-
序列不会"最大化"。它们的最大值是10 ^ 28。因此,即使您每秒获得一千个值,也需要花费很长时间才能达到最大值。
-
@a_horse_with_no_name除非Oracle的某个人实施CC& B,否则决定强制序列上的MAX_VALUE为999 ......但原则上,是的,你是对的(再次)。
如果不移动迭代器,则循环肯定是无限的(只要至少有一个元素)。
使用Iterator.next()移动迭代器
1 2 3 4
| while (iterator. hasNext()) {
Object nextElement = iterator. next();
LOG. info("Next element is:" + nextElement );
} |
也许你在编写代码时考虑了ResultSet.next(),但是迭代器是不同的。 看看javadocs。
-
咄! 我应该知道的更好。 谢谢你指出我失明的那一刻。 +1并接受。
使用Oracle DB时,我建议使用序列。
要使序列起作用,您应该在映射文件中定义列和序列名称,Hibernate将完成获取下一个序列值的工作。
供参考:
SQL Server - 使用Identity进行自动增量
MySQL / Maria DB - 使用自动增量
PostgreSQL - 使用序列或者..
PostgreSQL自动增量
警报:试图找到列中的最大值并将其弹起是不可接受的设计。
-
感谢+1关于Hibernate通过简单地定义hbm.xml文件中的内容来完成获取下一个序列值的工作。 我在哪里可以了解更多相关信息? 一个具体的例子就是超级。 谢谢!
-
stackoverflow.com/questions/5082175/…
-
有关详细示例,请访问:stackoverflow.com/questions/2155376/…