2016-05-29 23 views
5

Tôi đang cố gắng chèn vào bản ghi mới vào postgresql của mình bằng Hibernate và Java EE.Hibernate: giá trị khóa trùng lặp vi phạm ràng buộc duy nhất

Đây là mô hình của tôi:

@Entity 
@SuppressWarnings("serial") 
@Inheritance(strategy=InheritanceType.JOINED) 
public class BaseDesign implements Serializable { 

    @Id 
    @Expose 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "id", updatable = false, nullable = false) 
    private Long id; 

    @Version 
    @Column(name = "version") 
    private int version; 

    @Expose 
    @Column(name = "name") 
    private String name; 

    // getter and setter 
} 

Và đây là import.sql tôi

INSERT INTO basedesign (id, name, version) VALUES (1, 'China', 0); 

Khi tôi xây dựng mã, hồ sơ được thêm vào db.

Tuy nhiên, khi tôi cố gắng thêm một kỷ lục mới sử dụng EntityManager, như thế này:

BaseDesign design = new BaseDesign(); 
design.setName("USA");     
em.persist(design); 

tôi nhận:

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

Thực hiện lệnh tương tự cho lần thứ hai, và nó thành công.

Tại sao Hibernate không tăng ID khởi đầu ở lần đầu tiên? Và làm thế nào để cấu hình nó để bắt đầu tại số nguyên được chèn cuối cùng?

Trả lời

7

Khi bạn tạo cột bigserial trong Postgresql, bạn are actually creating a sequence. Khi bạn tự chèn một giá trị ID là '1', Postgresql không cập nhật chuỗi để tính đến điều này. Hibernate cho phép Postgresql sử dụng trình tự để tạo ID, nhưng giá trị đầu tiên được tạo ra là '1', nó sẽ gặp sự cố. Giá trị thứ hai là tốt.

Nếu bạn đã tạo vấn đề bằng cách đi đằng sau Hibernate và sử dụng SQL trực tiếp, bạn nên sửa chữa nó theo cùng một cách: use ALTER SEQUENCE to set the next value:

alter sequence basedesign_id_seq restart with 2; 
+0

Vì vậy, giải pháp này phải gán một số biết đến nó? Nó không thể tự động nhận id cuối cùng? – VHanded

+1

Vấn đề là câu lệnh chèn SQL của bạn đã chèn ID theo cách thủ công. Hệ thống có thể tự động nhận ID, miễn là bạn * luôn * để hệ thống tạo ID và không bao giờ cung cấp giá trị cho cột id. –

+0

Cảm ơn. Những gì tôi đang cố gắng đạt được, là một bản sao lưu và khôi phục. Khi tôi tạo một tệp kết xuất từ ​​DB, nó đi kèm với câu lệnh INSERT có ID trong đó. Vì ID đó không được tạo bởi DB, nó gây ra vấn đề trên. – VHanded

Các vấn đề liên quan