如何强制休眠以同步序列?

时间:2018-09-17 07:48:27

标签: java postgresql hibernate jpa

我尝试使用测试数据准备集成测试。我从外部文件读取插入查询,并将其作为本机查询执行。插入后,我执行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数据源和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 );结尾了该脚本。我在第一个持久命令之前设置一个断点,检查postgresql db中的序列,该序列具有最大id值16。现在持久工作,并且条目具有id17。脚本在实体管理器启动和休眠之前执行启动时阅读更新的序列。但是此解决方案无法回答我的问题。

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

1 个答案:

答案 0 :(得分:0)

如果策略是“身份”,则意味着休眠将创建一个序列表并从中获取ID,通过使用本机sql,您只是插入自己的值而无需更新该表,因此您有两个解决方案

  • 在您的计算机中使用休眠本身进行插入将非常容易 集成测试注入您的DAO,让冬眠进行插入 建议您这样做,因此您无需重新处理 休眠已处理
  • 每当您执行插入操作时,通过递增序列号来更新序列表 我不推荐的值。