我正在尝试将我们的一项服务迁移到Spring Boot 2.0.3。 尽管大多数测试都可以,但是其中一项失败并显示错误:
Caused by: org.h2.jdbc.JdbcSQLException: Sequence "HIBERNATE_SEQUENCE" not found; SQL statement:
call next value for hibernate_sequence [90036-197]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:357)
at org.h2.message.DbException.get(DbException.java:179)
at org.h2.message.DbException.get(DbException.java:155)
at org.h2.command.Parser.readSequence(Parser.java:5970)
at org.h2.command.Parser.readTerm(Parser.java:3131)
at org.h2.command.Parser.readFactor(Parser.java:2587)
这确实令人困惑,因为所有实体都依赖于相同的世代ID机制:
@GeneratedValue(strategy = GenerationType.AUTO)
这是一个存储库测试,存储库本身非常简单:
@Repository
public interface OrderDetailsRepository extends JpaRepository<OrderDetails, Long> {
OrderDetails findFirstByOrderIdOrderByIdDesc(String orderId);
}
这里可能出什么毛病?
PS:,是的,实体中同时存在orderId
和Id
字段。
答案 0 :(得分:3)
选择@GeneratedValue(strategy = GenerationType.AUTO)
时,Hibernate将基于特定于数据库的方言选择一种生成策略。
您遇到的问题是休眠状态无法找到HIBERNATE_SEQUENCE,因此无法为该序列创建新对象。尝试添加这样的序列,它应该可以解决问题,但可能导致数据不一致...
CREATE TABLE CUSTOMER(
id int primary key,
);
CREATE SEQUENCE HIBERNATE_SEQUENCE START WITH 1 INCREMENT BY 1;
我建议您使用GenerationType.SEQUENCE
,然后尝试使用自定义数据库序列重新创建ID模式。您可以阅读有关GenerationType的更多信息
here
答案 1 :(得分:1)
用h2编写用于Spring Boot的示例代码时遇到了相同的问题。请在下面找到我的发现的细节。 在您的实体类序列中没有给出并检查您的表,即您是否给定AUTO_INCREMENT作为主键?
请按照以下说明进行操作。 1.一次检查您的ddl并将主键设置为auto_increment(有关ID,请参见下文)
CREATE TABLE EMPLOYEES (
id INT AUTO_INCREMENT PRIMARY KEY,
first_name VARCHAR(250),
last_name VARCHAR(250),
email VARCHAR(250) DEFAULT NULL
);
检查您的实体类并更新主键,如下所示
公共类员工{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
请注意,GenerationType被赋予IDENTITY,您也可以赋予AUTO。另外,如果您使用的是h2内存数据库,并且在启动启动时插入了很少的表记录(如果dml文件在资源中可用),则休眠插入可能会给出唯一的约束,因为序列1,2,3 ..(取决于插入的记录数)就像我在上面说过的那样,冬眠会从1生成序列,并且每次新插入都会加1。因此,我建议不要在引导启动时插入记录,而最好以编程方式插入。
为了您的学习,您可以使用上面给出的方法,但是如果可以在生产中使用,则最好实现自己的逻辑以生成序列。
答案 2 :(得分:1)
我有类似的问题。如果我理解正确,它就会像这样下去。
在Spring升级之前,我使用AUTO-但实际上默认情况下选择了IDENTITY策略。我有如下定义的自动递增PK:
id BIGINT AUTO_INCREMENT PRIMARY KEY
一切都很好。
在春季升级中,我必须指定H2方言:
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
我读到,如果您使用Hibernate作为持久性提供程序,它将基于数据库特定的方言选择一种生成策略。对于H2,它可能选择了全局序列(根据JPA规范,这就是AUTO的意思)-并且找不到序列。 解决方案当然是创建序列(如上所述),或手动替代原来自动选择的IDENTITY。
CREATE SEQUENCE HIBERNATE_SEQUENCE START WITH 1 INCREMENT BY 1;
@GeneratedValue(strategy = GenerationType.IDENTITY)
我认为根本原因是在时间上AUTO的含义不明确/定义不清/理解不正确。可能原来从“自动”切换到IDENTITY基本上是一个错误。