唯一索引或主键违规: "PRIMARY KEY ON PUBLIC.xxx"; SQL语句

21 浏览
0 Comments

唯一索引或主键违规: "PRIMARY KEY ON PUBLIC.xxx"; SQL语句

每当我的应用程序启动时,我会收到以下错误消息:

Caused by: org.h2.jdbc.JdbcSQLException: 违反唯一索引或主键约束:"PRIMARY KEY ON PUBLIC.SERMON_SESSION(ID)"; SQL 语句:
INSERT INTO SERMON_SESSION (id, session_enum) VALUES ('1', 'SUN_MRN'), ('2', 'SUN_EVE'), ('3', 'TUE_BIB'), ('4', 'FRI_BIB'), ('5', 'WKD_CNF') [23505-197]

我该如何修复这个问题?因为后续的列中会使用讲道会话id,所以我必须自己分配它。

application.properties

spring.h2.console.enabled=true

spring.h2.console.path=/h2

spring.datasource.url=jdbc:h2:mem:erc;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE

spring.datasource.driver-class-name=org.h2.Driver

spring.datasource.username=sa

spring.datasource.password=

spring.datasource.initialization-mode=embedded

spring.jpa.properties.hibernate.hbm2ddl.import_files=classpath://resources/data.sql

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect

spring.jpa.show-sql=false

spring.jpa.hibernate.ddl-auto=create-drop

spring.jpa.properties.hibernate.hbm2ddl.import_files_sql_extractor=org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor

logging.level.com.erc.api.*=DEBUG

logging.level.org.hibernate=OFF

logging.level.org.hibernate.SQL=INFO

logging.level.org.hibernate.type.descriptor.sql=INFO

logging.level.org.jaudiotagger=WARN

spring.servlet.multipart.max-file-size=60MB

spring.servlet.multipart.max-request-size=60MB

application.sermon_path=classpath://resources/files/sermons/}

SermonSession.java

@Table(name = "sermon_session", uniqueConstraints = @UniqueConstraint(columnNames = {"id", "sessionEnum"}))
@Entity
public class SermonSession {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(updatable = false, nullable = false, unique = true)
    private int id;
    @Enumerated(EnumType.STRING)
    @Column(unique = true)
    private SessionEnum sessionEnum;
    public SermonSession(String session) {
        setSessionEnum(session);
    }
    public SermonSession() {
        this.sessionEnum = null;
    }
    public String toString() {
        return String.format("{ id: %d, session_enum: %s }", getId(), getSessionEnum());
    }
    String getSessionEnum() {
        return this.sessionEnum.getSession();
    }
    private void setSessionEnum(String session) {
        this.sessionEnum = SessionEnum.fromSession(session);
    }
    private int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
}

data.sql

INSERT INTO SERMON_SESSION (id, session_enum)
VALUES ('1', 'SUN_MRN'),
       ('2', 'SUN_EVE'),
       ('3', 'TUE_BIB'),
       ('4', 'FRI_BIB'),
       ('5', 'WKD_CNF');

将data.sql更改为:

INSERT INTO SERMON_SESSION (session_enum)
VALUES ('SUN_MRN'),
       ('SUN_EVE'),
       ('TUE_BIB'),
       ('FRI_BIB'),
       ('WKD_CNF');

会产生以下错误消息:

Caused by: org.h2.jdbc.JdbcSQLException: 违反唯一索引或主键约束:"UK_AA7KWY8HO9GLHF1VI4HDB61X8_INDEX_8 ON PUBLIC.SERMON_SESSION(SESSION_ENUM) VALUES ('SUN_MRN', 1)"; SQL 语句:
INSERT INTO SERMON_SESSION (session_enum) VALUES ('SUN_MRN'), ('SUN_EVE'), ('TUE_BIB'), ('FRI_BIB'), ('WKD_CNF') [23505-197]

0
0 Comments

问题的原因是在插入数据时违反了唯一索引或主键的限制。在执行INSERT语句时,发生了唯一索引或主键冲突的错误。

解决方法是在插入数据之前,首先删除表中的数据。可以使用DELETE语句来删除表中的所有数据。如果在执行DELETE语句时出现错误,可能是由于存在约束导致无法删除数据。此时,可以尝试使用TRUNCATE TABLE语句来清空表中的数据。

具体操作如下:

DELETE FROM SERMON_SESSION;
INSERT INTO SERMON_SESSION (session_enum)
VALUES ('SUN_MRN'),
       ('SUN_EVE'),
       ('TUE_BIB'),
       ('FRI_BIB'),
       ('WKD_CNF');

如果在执行DELETE语句时出现错误,可以尝试使用TRUNCATE TABLE语句:

TRUNCATE TABLE SERMON_SESSION;

通过删除表中的数据,然后再插入新的数据,可以解决唯一索引或主键冲突的问题。

0
0 Comments

最近我遇到了类似的问题。问题可能是,当你没有正常关闭应用程序(没有向应用程序的端点发送消息以进行关闭)时,会话管理器可能没有机会执行删除操作(请参阅此主题:Spring boot ddl auto generator)。

我们找到的解决方法是手动删除数据库并将

spring.jpa.hibernate.ddl-auto=create

更改为

spring.jpa.hibernate.hbm2ddl.auto=create

为什么会这样?我仍在等待答案

我尝试了这个方法,但出现了错误:org.h2.jdbc.JdbcSQLException: Cannot truncate "PUBLIC.SERMON_SESSION"; SQL statement: TRUNCATE TABLE SERMON_SESSION [90106-197]

0
0 Comments

对我来说,我遇到了完全相同的错误消息。它没有影响我的CRUD操作,但仍然让人讨厌。我按照这篇文章的步骤解决了这个错误。

TLDR

要解决这个问题,将主键列的值设置为唯一且非空。只需在DDL的末尾添加NOT NULL UNIQUE即可解决。

0