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

Hibernate无法持久化保存对象至H2数据库问题求助

问题定位与解决方案

1. 核心问题:事务未提交

你的createInitialObjects方法未被@Transactional注解标记,导致Hibernate的持久化操作(persist/merge)处于无事务上下文环境中。Spring框架下,EntityManager的数据库操作默认需要在事务内执行,否则所有操作会在方法结束后自动回滚,不会真正写入数据库。尽管Hibernate日志打印了insert语句,那仅代表SQL已生成,并未实际提交到数据库。

解决方法:
在createInitialObjects方法上添加事务注解:

import org.springframework.transaction.annotation.Transactional;

@Transactional
@Override
public void createInitialObjects() {
    // 原有代码保持不变
}

2. ID判断逻辑错误

你的save方法仅在对象id等于0L时调用persist,但创建的对象id是-1L,导致实际执行的是merge操作。虽然merge对新对象也会触发insert,但这种判断逻辑不符合预期,容易引发逻辑混淆。

解决方法:
修改save方法的判断逻辑,覆盖所有无效ID场景:

@Override
public Object save(Object object) {
    if (object.getId() == null || object.getId() <= 0) {
        em.persist(object);
    } else {
        object = em.merge(object);
    }
    return object;
}

3. 手动设置ID与序列生成策略冲突

从日志可见你使用cabin_sequence生成ID,但创建对象时手动设置了id=-1L。如果实体类ID字段配置了@GeneratedValue(strategy=GenerationType.SEQUENCE),手动设置ID会干扰Hibernate的ID生成逻辑,可能导致插入的ID不符合预期,甚至引发主键冲突。

解决方法:

  • 修改createSampleObject方法,不手动设置ID,交由Hibernate通过序列自动生成:
public static Object createSampleObject() {
    Object obj = new Object();
    // 仅赋值其他属性,不要设置id字段
    return obj;
}
  • 确保实体类的ID注解配置正确:
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "cabin_sequence")
@SequenceGenerator(name = "cabin_sequence", sequenceName = "cabin_sequence", allocationSize = 1)
private Long id;

验证步骤

  1. 添加@Transactional注解后重新运行程序;
  2. 通过H2控制台(默认路径http://localhost:8080/h2-console)查看object表是否存在数据;
  3. 若问题依旧,检查实体类ID生成策略配置,确保未手动设置无效ID值。

内容的提问来源于stack exchange,提问作者matthijs

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 05:31:23