在我的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
?
答案 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;