Spring Data PostgreSQL Key已存在错误2

时间:2016-03-19 09:03:24

标签: java postgresql jpa spring-data

在我的Spring Boot / Data / JPA应用程序中,我有一个以下的PostgreSQL表:

CREATE TABLE IF NOT EXISTS levels (
    id SERIAL PRIMARY KEY,
    name VARCHAR(256),
    created_date timestamp,
    updated_date timestamp
);

和Spring Data / JPA实体:

@Entity
@Table(name = "levels")
public class Level extends BaseEntity implements Serializable {

    private static final long serialVersionUID = 642499791438799548L;

    @Id
    @SequenceGenerator(name = "levels_id_seq", sequenceName = "levels_id_seq", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "levels_id_seq")
    private Long id;

    private String name;

...
}

另外,我在数据库中添加了10个级别:

    INSERT INTO levels (id, name) VALUES (1, 'Level 1') ON CONFLICT (id) DO NOTHING;
    INSERT INTO levels (id, name) VALUES (2, 'Level 2') ON CONFLICT (id) DO NOTHING;
    INSERT INTO levels (id, name) VALUES (3, 'Level 3') ON CONFLICT (id) DO NOTHING;
    INSERT INTO levels (id, name) VALUES (4, 'Level 4') ON CONFLICT (id) DO NOTHING;
    INSERT INTO levels (id, name) VALUES (5, 'Level 5') ON CONFLICT (id) DO NOTHING;
    INSERT INTO levels (id, name) VALUES (6, 'Level 6') ON CONFLICT (id) DO NOTHING;
    INSERT INTO levels (id, name) VALUES (7, 'Level 7') ON CONFLICT (id) DO NOTHING;
    INSERT INTO levels (id, name) VALUES (8, 'Level 8') ON CONFLICT (id) DO NOTHING;
    INSERT INTO levels (id, name) VALUES (9, 'Level 9') ON CONFLICT (id) DO NOTHING;
    INSERT INTO levels (id, name) VALUES (10, 'Level 10') ON CONFLICT (id) DO NOTHING;

当我尝试创建新关卡时:

@Repository
public interface LevelRepository extends JpaRepository<Level, Long> {

    Level findByName(String name);

}

level = new Level();
level.setName(name);
level = levelRepository.save(level);

我收到以下异常:

ERROR:  duplicate key violates unique constraint « levels_pkey »
DETAIL: Key "(id)=(1)" already exists.

为什么系统会选择id=1而不是11

1 个答案:

答案 0 :(得分:4)

序列生成器从1开始,并在每次插入后通过JPA实现框架或在insert语句中使用call to generator进行递增。如果使用RDBMS序列生成器,则不应在原始SQL中插入硬编码的ID值。

现在您可以修复序列:

ALTER SEQUENCE levels_id_seq
  INCREMENT 1
  MINVALUE 11
  MAXVALUE 9223372036854775807
START 11
CACHE 1;
ALTER TABLE levels
  OWNER TO postgres;

或修复插件,如:

INSERT INTO levels (id, name) VALUES (nextval(levels_id_seq), 'Level 1') ON CONFLICT (id) DO NOTHING;