hibernate org.postgresql.util.PSQLException:错误:重复键值违反了persist()上没有ID的唯一约束?

eaf3rand  于 2023-03-03  发布在  PostgreSQL
关注(0)|答案(1)|浏览(146)

我在Hibernate中遇到了一个异常,这个异常对我来说毫无意义。我正在使用persist()方法来存储一个新的、没有ID的独立实体(所以它不会导致分离实体传递异常).我甚至在传递它之前显式地将实体的ID设置为null.所以据我所知,自动增量将为要保存的新实体生成新ID(它也在传递的对象中变异,以便在方法调用后使用)。至少对我来说,这是它一直以来的工作方式。然而,在这段代码中发生了一些非常奇怪的事情,我想不出为什么,也许是一些小问题。当我调用这个代码时:

@Transactional
    public Settings createSettingsFor(Long id, Settings settings) {
        // Setting the ID explicitely to null here, to be sure it is not set before persist
        settings.setId(null);
        // Exception triggers here
        entityManager.persist(settings);
        entityManager.flush();
        // Attempting to link the newly created setting with another table entity manually, since i initially thought the error might be here but, but its caused before
        entityManager
            .createNativeQuery("UPDATE bots b WHERE b.id = :id SET b.settings_id = :settings_id")
            .setParameter("id", id)
            .setParameter("settings_id", settings.getId())
            .executeUpdate();
        return settings;
    }

我得到以下异常:

org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "settings_pkey"
  Detail: Key (id)=(1) already exists.

现在,问题是:设置表中确实已经有一个ID为1的条目,这是创建数据库时生成的默认设置。**但是,为什么hib要选择一个已经在使用的ID来持久化一个新的、未附加的实体(没有ID)?**我认为这一定是一些奇怪的缓存问题,但我现在已经重新构建了应用程序十几次。

blpfk2vs

blpfk2vs1#

我想通了,问题是“设置”表的表模式是用身份序列提供程序使用“START WITH 1”生成的:

ALTER TABLE settings ALTER COLUMN id ADD GENERATED BY DEFAULT AS IDENTITY (
    SEQUENCE NAME settings_id_seq
    START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    NO MAXVALUE
    CACHE 1
);

这显然意味着它将始终强制从1开始,即使已经存在ID为1的条目。

相关问题