当前位置: 首页 > 面试题库 >

优化休眠序列ID生成

干稳
2023-03-14
问题内容

尝试将Hibernate与SAP
HANA内存数据库连接时遇到一些性能问题,该数据库不支持AUTO_INCREMENT(http://scn.sap.com/thread/3238906)。

因此,我将Hibernate设置为使用序列进行ID生成。

  @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="myseq") 
  @SequenceGenerator(name="myseq",sequenceName="MY_SEQ",allocationSize=1)

但是,当我插入大量记录(例如40000)时,Hibernate首先会生成ID。看起来像:

DEBUG Thread-1 org.hibernate.SQL - select MY_SEQ.nextval from DUMMY
DEBUG Thread-1 org.hibernate.id.SequenceGenerator - Sequence identifier generated: BasicHolder[java.lang.Long[92080]]
DEBUG Thread-1 org.hibernate.event.internal.AbstractSaveEventListener - Generated identifier: 92080, using strategy: org.hibernate.id.SequenceHiLoGenerator
DEBUG Thread-1 org.hibernate.SQL - select MY_SEQ.nextval from DUMMY
DEBUG Thread-1 org.hibernate.id.SequenceGenerator - Sequence identifier generated: BasicHolder[java.lang.Long[92081]]
DEBUG Thread-1 org.hibernate.event.internal.AbstractSaveEventListener - Generated identifier: 92081, using strategy: org.hibernate.id.SequenceHiLoGenerator

并且只有在生成所有ID之后,它才开始实际插入。

总之,大约需要5分钟才能插入40000条记录(通过网络到远程数据库),这对于内存数据库来说非常慢。我认为发生这种情况是因为Hibernate一对一地选择了ID的下一个值:

send a request to database
get id
send next request
...

我想加快ID生成的速度,但是不幸的是,我对ID如何改进它还不够了解。我搜索了可能的解决方案,并发现以下想法:

1) 在insert语句中调用sequence.nextval
。但是,Hibernate小组说这是不可能的:https
:
//forum.hibernate.org/viewtopic.php?f=1&t=932506

2) 使用SequenceHiLoGenerator 。这可能是一个解决方案,但我不知道如何设置…如果我写

  @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="myseq") 
  @SequenceHiLoGenerator(name="myseq",sequenceName="MY_SEQ",allocationSize=1),

我在Eclipse中收到“无法从SequenceHiLoGenerator转换为注释”错误

3) 在inserts上编写一个数据库触发器 。但是,对我来说,这似乎是一个糟糕的解决方案,因为我想让通用的Hibernate
Dialect与任何数据库实例一起使用。而且我不了解如何在Hibernate方言中包含这样的触发器。

您会建议哪种解决方案? 你还有其他建议吗?

在此问题上的任何帮助,我将由衷的感谢。如果有人可以提供一些解决方案或文档,或者甚至只是提供解决方案的更详细途径,那将是很好的。

提前非常感谢您。


问题答案:

序列中的值被一一读取,因为allocationSize设置为1。默认值为allocationSize50,这已经更好了。在这种特殊情况下,如果插入40000条记录是典型的用例,则使用高于该值的值可能是有意义的。

如果用于创建序列的脚本是自行编写的(而不是由Hibernate编写),则的值INCREMENT BY应与的值相同allocationSize



 类似资料:
  • 问题内容: 我的数据库是Oracle,我的id列值是Oracle序列,此序列由触发器执行,因此,在插入每一行之前,此触发器使用此序列来获取id值。因此,我对应该在实体类中定义哪个id策略生成感到困惑。 要么 要么 真的很困惑,有人可以阐明这个话题吗?请清楚解释。 问题答案: 我还有一个projet,其中有一个Oracle DB将数据提供给我的@Entity类。如您所说,序列通过触发器生成表PK的I

  • 问题内容: 是否可以对 不是标识符/不是复合标识符一部分的 某些列使用DB序列? 我正在将hibernate用作jpa提供程序,并且我有一个表,其中包含一些生成的值(使用序列)的列,尽管它们不是标识符的一部分。 我想要的是使用序列为实体创建新值,其中序列的列 不是 主键(的一部分): 然后,当我这样做时: 该ID将被生成,但该属性也将由我的JPA提供程序生成。 为了清楚起见:我希望 Hiberna

  • 我在尝试将HiberNate与SAP HANA In-Memory数据库连接时遇到了一些性能问题,该数据库不支持AUTO_INCREMENT(http://scn.sap.com/thread/3238906)。 因此,我将HiberNate设置为使用序列生成ID。 但是当我插入大量记录(例如,40000)时,Hibernate首先会生成ID。它看起来像: 只有在生成所有 ID 后,它才会开始实际

  • 问题内容: 任何人都知道一些有关如何为hibernate创建自定义ID生成器的好教程吗? 问题答案: 在Google上粗略搜索“hibernate自定义ID生成器教程”,发现了以下可能性。我排除了那些看起来没有用的内容,并总结了它们的内容。 http://www.devx.com/Java/Article/30396-涵盖了在数据保留之前生成ID(因此还没有业务密钥)的问题。 http://doc

  • 问题内容: 这将创建以下架构: 观察:当我将序列设置为1时,第一个自动生成的是。当我将值设置为时,第一个ID为。 于是,不知何故该序列的当前valuze总是得到 成倍 的。为什么?如何防止这种情况,而只使用序列中的nexval? 问题答案: 此行为来自其参数的默认值50 。您可以根据需要进行更改: 这是出于性能原因。它允许Hibernate预订ID块,并防止每次需要新ID时都询问数据库。

  • 问题内容: 有谁知道那里是否有一个能够从实体类中剥离Hibernate集合以使其可序列化的框架?我看了一下BeanLib,但它似乎只做实体的深层副本,而不允许我为实体类中的集合类型指定实现映射。BeanLib当前不适用于Hibernate 3.5和Spring 3(我确实修改了源代码并能够使其正常工作,但我不想这样做)。吉利德(Gilead)似乎是一个选择,但它似乎具有侵入性。我宁愿使用简单的深度