【问题标题】:How force hibernate to sync sequences?如何强制休眠来同步序列?
【发布时间】:2018-09-17 07:48:26
【问题描述】:

我尝试使用测试数据准备集成测试。我从外部文件中读取插入查询并将它们作为本机查询执行。插入后我执行select setval('vlan_id_seq', 2000, true );。这是实体 ID 定义:

@Id
@Column(name = "id", unique = true, nullable = false)
@GeneratedValue(strategy = IDENTITY)
private Integer id;

当我尝试持久化一个新条目时,我收到了 Caused by: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "vlan_pkey" Detail: Key (id)=(1) already exists. 异常。该序列的ID为2000。列定义由serial宏完成,为id integer NOT NULL DEFAULT nextval('vlan_id_seq'::regclass)

我在用户事务中执行了本机查询,因此所有测试条目都存储在 postgresql 数据库中,但似乎休眠不同步序列。 entityManager.flush(); 也没有强制进行序列同步。似乎休眠没有使用带有@GeneratedValue(strategy = IDENTITY) 的序列。我使用 XA-Datasource 和 wildfly 13。

我现在测试了另一种初始化方法。我在 persitence.xml (javax.persistence.sql-load-script-source) 中定义了一个 SQL 数据脚本(我用Jailer 生成了脚本),并用select pg_catalog.setval('vlan_id_seq', (SELECT max(id) FROM vlan), true ); 结束了脚本。我在第一个persist命令之前设置了一个断点,检查postgresql db中的序列,序列的最大id值为16。现在持久化工作并且条目的id为17。脚本在实体管理器启动和休眠之前执行开始时读取更新的序列。但是这个解决方案没有回答我的问题。

hibernate 是否有可能重新读取序列以使用 nextval 值?

【问题讨论】:

    标签: java postgresql hibernate jpa


    【解决方案1】:

    如果策略是 Identity,这意味着 Hibernate 将创建一个序列表并从中获取 ID,通过使用本机 sql,您只需插入自己的值而不更新该表,因此您有 两种解决方案

    • 使用 hibernate 本身插入,这将相当容易,在您的 集成测试注入您的 DAO 并让 hibernate 进行插入 为您推荐,因此您无需重新处理 休眠已处理
    • 每当您通过递增插入时更新序列表 我不推荐的值。

    【讨论】:

    • 如何访问此表?我在文档中一无所获。 Hibernate 创建一个以 postgresql 命名的 SQL 序列并仅在启动时访问该序列?这很令人困惑,因为当我之前使用原生查询select currval('vlan_id_seq') 读取序列时,我得到了 2000。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-02
    • 2017-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多