You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用JPA+Hibernate+HSQL 2.4.1持久化新对象时遇权限/序列异常

解决Hibernate持久化Client时HIBERNATE_SEQUENCE找不到的问题

你遇到的核心问题是Hibernate试图调用hibernate_sequence序列生成主键,但你的HSQLDB数据库中并没有创建这个序列,因此抛出了权限/对象找不到的错误。而查询功能正常是因为表和初始数据已经存在,查询操作不需要依赖序列。下面来拆解问题根源和具体解决方案:

问题根源

你在实体类中使用了@GeneratedValue(strategy = GenerationType.AUTO),Hibernate在与HSQLDB配合时,默认会把AUTO策略解析为SEQUENCE模式,它会尝试执行call next value for hibernate_sequence来获取下一个主键值。但你的数据库是通过自定义create.sql脚本创建的,里面并没有定义这个序列,所以触发了异常。

解决方案

方案1:改用IDENTITY自增主键策略(推荐,适配HSQLDB特性)

HSQLDB原生支持自增列,你可以直接切换主键生成策略为IDENTITY,让Hibernate利用数据库的自增机制生成主键,彻底摆脱对序列的依赖。

步骤1:修改实体类的主键注解

@Entity
@Table(name = "client")
public class Client {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY) // 替换为IDENTITY策略
    @Column(name = "id")
    private Long id;
    // 其他字段、getter和setter
}

步骤2:确保create.sql中的id列是自增类型

检查你的sql/create.sql脚本,确保client表的id列定义为自增:

CREATE TABLE client (
    id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    first_name VARCHAR(255) NOT NULL,
    second_name VARCHAR(255) NOT NULL,
    patronymic VARCHAR(255),
    number VARCHAR(255) NOT NULL
);

方案2:手动创建Hibernate需要的序列

如果你坚持使用SEQUENCE策略,需要在create.sql中手动创建Hibernate默认使用的hibernate_sequence。

步骤1:在create.sql中添加序列创建语句

-- 先创建Hibernate默认序列
CREATE SEQUENCE hibernate_sequence START WITH 1 INCREMENT BY 1;
-- 再创建client表
CREATE TABLE client (
    id BIGINT PRIMARY KEY,
    first_name VARCHAR(255) NOT NULL,
    second_name VARCHAR(255) NOT NULL,
    patronymic VARCHAR(255),
    number VARCHAR(255) NOT NULL
);

可选:自定义序列名称(更规范)

如果不想使用默认的hibernate_sequence,可以在实体类中指定自定义序列:

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "client_seq")
@SequenceGenerator(name = "client_seq", sequenceName = "client_sequence", allocationSize = 1)
@Column(name = "id")
private Long id;

同时在create.sql中创建对应的序列:

CREATE SEQUENCE client_sequence START WITH 1 INCREMENT BY 1;

额外优化:清理persistence.xml的冲突配置

你的persistence.xml中有几处配置冲突,可能导致意外行为,建议调整:

  • javax.persistence.schema-generation.database.action和hibernate.hbm2ddl.auto同时设置,建议统一逻辑:如果依赖自定义create.sql,把hibernate.hbm2ddl.auto设为none,避免Hibernate自动修改schema。
  • javax.persistence.sql-load-script-source和hibernate.hbn2ddl.import_files重复,保留其中一个即可。

调整后的persistence.xml示例:

<persistence-unit name="mainPU" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <class>com.haulmont.testtask.data.entity.Client</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
        <property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver"/>
        <property name="javax.persistence.jdbc.url" value="jdbc:hsqldb:file:db-data/test_task;shutdown=true"/>
        <property name="javax.persistence.jdbc.user" value="SA"/>
        <property name="javax.persistence.jdbc.password" value=""/>
        <property name="javax.persistence.schema-generation.database.action" value="create"/>
        <property name="javax.persistence.schema-generation.create-source" value="script"/>
        <property name="javax.persistence.schema-generation.create-script-source" value="sql/create.sql"/>
        <property name="javax.persistence.sql-load-script-source" value="sql/import.sql"/>
        <property name="hibernate.hbm2ddl.import_files_sql_extractor" value="org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor"/>
        <property name="hibernate.show_sql" value="true"/>
        <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
        <property name="hibernate.hbm2ddl.auto" value="none"/> <!-- 修改为none避免冲突 -->
    </properties>
</persistence-unit>

内容的提问来源于stack exchange,提问作者Сергей Херувимов

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:14:31