首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JPA主键自动生成

JPA主键自动生成
EN

Stack Overflow用户
提问于 2009-11-30 02:46:39
回答 3查看 108.9K关注 0票数 20

我的主键实体如下所示

代码语言:javascript
复制
@GeneratedValue(strategy= GenerationType.TABLE)
private Long id;

当我跑的时候,我会出错

无法获取或更新下一个值;嵌套异常为org.hibernate.exception.SQLGrammerException:could不获取或更新下一个值

但当我改变到

代码语言:javascript
复制
@GeneratedValue 
private Long id;

没有错误抛出。我希望在oracle db上为每个表生成唯一的主键。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-11-30 03:49:43

@GeneratedValue(strategy=GenerationType.TABLE)告诉JPA提供程序在将新创建的实体插入数据库时使用表获取ID。

当使用Hibernate作为提供程序时,这将导致一个表hibernate_sequences,它有两个列:实体名称和已经分配给该实体的最大标识。在这里,Hibernate似乎没有成功地为您的实体从它获得下一个ID,但是很难确切说明为什么,因为您没有为此提供足够的信息。

那么,您能提供完整的堆栈跟踪吗?此外,请将hibernate.show_sql属性设置为true的日志记录并设置正确的日志级别log4j.logger.org.hibernate.SQL=DEBUG。如果可能的话,加入日志回答你的问题。

也许只需检查您是否为Oracle配置了正确的hibernate.dialect。实际上,如果可能的话,也加入您的hibernate配置。

PS:用Oracle生成PK的“传统”方法是使用序列(您可以让Hibernate使用GenerationType.AUTO猜测数据库类型的最佳策略,或者强制使用SEQUENCE),但我假设您希望结果数据结构与数据库无关。如果没有,我建议用序列代替。

编辑:回答OP中关于GenerationType.AUTO的评论。实际上,默认情况是一个名为hibernate_sequence的全局序列,这可能是一个问题。但是,通过下面所示的设置,您可以使用GenerationType.AUTO并仍然控制数据库使用序列的情况下序列的名称:

代码语言:javascript
复制
@Id
@GeneratedValue(strategy=GenerationType.AUTO, generator="my_entity_seq_gen")
@SequenceGenerator(name="my_entity_seq_gen", sequenceName="MY_ENTITY_SEQ")
private long id;

换句话说,您可以对每个表使用不同的序列名称,而不会失去可移植性。

票数 37
EN

Stack Overflow用户

发布于 2014-12-22 02:57:30

在JPA中有4种自动生成策略:

  • 自动
  • 身份
  • 序列
  • 表格

对于Oracle自动生成主键注释,Sequence和Table是您的选择。基本逻辑是先定义生成器,分别使用@SequenceGenerator@TableGenerator,然后在@GeneratedValue.中使用生成器作为属性。

以下是如何使用序列策略的示例:

代码语言:javascript
复制
  @Id
  @SequenceGenerator(name="SEQ_GEN", sequenceName="SEQ_JUST_FOR_TEST", allocationSize=1)
  @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_GEN")
  private long id;

下面是如何使用表策略的示例:

代码语言:javascript
复制
  @Id
  @TableGenerator(name="TABLE_GEN",table="T_GENERATOR", pkColumnName = "GEN_KEY", pkColumnValue = "MONITOR2012.T_JUST_FOR_TEST", valueColumnName = "GEN_VALUE", initialValue = 1, allocationSize = 1 )
  @GeneratedValue(strategy = GenerationType.TABLE, generator="TABLE_GEN")
  private long id;

如果没有在@GeneratedValue注释中指定生成器,则选择将留给JPA实现。

如果使用现有表处理数据库,请在运行应用程序之前确保数据库中定义的序列或表。表生成器还需要在@GeneratedValue注释能够正常工作之前将一行插入到表中。

下面是关于如何为Oracle数据库在JPA中配置主密钥自动生成的教程。

票数 10
EN

Stack Overflow用户

发布于 2021-09-18 05:59:04

标识:按需自动增量,由于数据库内部轻量级锁定而高效,但由于Hibernate采用的“事务性写后”刷新策略,hibernate不能很好地与Hibernate一起工作。

序列:预先分配值以提高性能,支持良好的休眠“事务性写写”刷新策略。

表(序列):可以使用一个或多个表来保存标识符序列计数器。但这意味着用写性能来换取数据库的可移植性。

汽车发电简介

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1817625

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档