小编典典

JPA主键自动生成

hibernate

我的主键实体如下所示

@GeneratedValue(strategy= GenerationType.TABLE)
private Long id;

当我跑步时,出现错误

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

但是当我改变为

@GeneratedValue 
private Long id;

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


阅读 349

收藏
2020-06-20

共1个答案

小编典典

@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;

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

2020-06-20