JPA主键自动生成

com*_*tta 17 java orm hibernate jpa oracle10g

我的主要密钥实体如下所示

@GeneratedValue(strategy= GenerationType.TABLE)
private Long id;
Run Code Online (Sandbox Code Playgroud)

当我跑,我得到错误

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

但是当我改变的时候

@GeneratedValue 
private Long id;
Run Code Online (Sandbox Code Playgroud)

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

Pas*_*ent 32

@GeneratedValue(strategy=GenerationType.TABLE)告诉JPA提供者使用一个表,从插入新创建的实体到数据库时,你得到的ID.

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

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

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

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

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

@Id
@GeneratedValue(strategy=GenerationType.AUTO, generator="my_entity_seq_gen")
@SequenceGenerator(name="my_entity_seq_gen", sequenceName="MY_ENTITY_SEQ")
private long id;
Run Code Online (Sandbox Code Playgroud)

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

  • 默认情况下,序列的最大数量为1E + 27或1,000,000,000,000,000,000,000,000,000,000.那应该够了:) (11认同)
  • 如果我把GenerationType.Auto,它将使用全局增量数字,意味着我的所有实体将增加相同的数字.代码运行正常,但它会用完增量数吗? (2认同)

She*_*g.W 10

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

  • 汽车
  • 身分
  • 序列

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

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

  @Id
  @SequenceGenerator(name="SEQ_GEN", sequenceName="SEQ_JUST_FOR_TEST", allocationSize=1)
  @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_GEN")
  private long id;
Run Code Online (Sandbox Code Playgroud)

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

  @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;
Run Code Online (Sandbox Code Playgroud)

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

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

以下是有关如何在JPA for Oracle数据库中配置主键自动生成的教程.