【问题标题】:Hibernate picking up second previous id value for next sequenceHibernate 为下一个序列获取第二个前一个 id 值
【发布时间】:2021-07-13 14:28:48
【问题描述】:

这是在我的实体类中配置 Id 的方式,

    @Entity
    @Table(name = "test_data")
    @NamedQuery(name = "TestData.findAll", query = "SELECT t FROM TestData t")
    public class TestData implements Serializable {
    @GenericGenerator(name = "testDataSequenceGenerator", strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator", parameters = {
            @Parameter(name = "sequence_name", value = "test_data_Seq"),
            @Parameter(name = "initial_value", value = "1000"), @Parameter(name = "increment_size", value = "1") })
    @Id
    @GeneratedValue(generator = "testDataSequenceGenerator")
    protected Long id;
    }

我将数据持久化到实现 JpaRepository 接口的表中。增量工作正常,直到我开发了一个新的 biz 解决方案,我需要根据 biz 需求插入 ID 值。

示例:我当前在 Postgres DB 中的第一行的 ID = 1000。因此,根据我在实体中完成的生成配置,我的下一个将是 1001。但是随着新的增强。我正在插入 ID = 2000。由于 JPA 不允许用户定义 ID(我相信这是因为 ID 上的配置),因此我使用本机查询通过 EntityManager 执行相同的操作。

现在这样做;一旦我运行根据用户输入插入 ID 的 biz 工作流程。后来,当我尝试创建一个新条目时,hibernate 使用之前创建的 ID 递增,即 1001,而不是 2001。

这是因为休眠中的任何缓存吗?我需要更新休眠中的下一个值吗?你能帮帮我吗?

【问题讨论】:

    标签: java spring-boot hibernate spring-data-jpa spring-data


    【解决方案1】:

    根据您的配置,您正在使用序列来生成 id (test_data_seq),而不使用休眠序列值缓存。当您手动设置 ID = 2000 时,序列的当前值不会被更新。您需要手动更新它,例如通过使用this function:

    SELECT setval('test_data_seq', 2000);
    

    在这种情况下,下一个生成的值应该是 2001。

    总体而言,如果您使用序列生成器,最好避免手动设置 id,因为发生冲突的风险很高。

    【讨论】:

    • 在这种情况下,假设。我已经执行了上述执行。我想插入另一个值 = 1500 的 ID。现在我不希望我的下一个 ID 是 1501。它应该仍然是 2001。我是否需要实现一个逻辑来找到更大的 Id 值或者是还有其他更好的方法。
    • 当前序列值将保持不变 (2001) - 手动插入的 id 值不会影响它。如果您插入一个低于当前序列一的值,您将不会遇到问题。关于附加逻辑-您可以通过多种方式处理它(就像您说的那样,要找到更大的值,您也可以故意插入低值,甚至是负值)。正如我所说,更好的方法是在同时使用序列时完全避免手动插入 id。
    • 同意。谢谢你的时间。 @amseager
    猜你喜欢
    • 1970-01-01
    • 2015-01-18
    • 1970-01-01
    • 2011-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-14
    相关资源
    最近更新 更多