简体   繁体   English

尝试在 Spring 启动应用程序中将行插入 H2 db 时出现主键冲突异常

[英]Primary Key violation exception when trying to insert rows into H2 db in Spring boot application

I am trying to create a Spring Boot application that will perform CRUD operation.我正在尝试创建一个将执行 CRUD 操作的 Spring Boot 应用程序。 But when I start the app, it terminates with an exception.但是当我启动应用程序时,它以异常终止。 I don't know what I am doing wrong.我不知道我做错了什么。 Here is my DDL and DML.这是我的 DDL 和 DML。 I don't know我不知道

schema.sql

CREATE TABLE IF NOT EXISTS Person(
    first_name VARCHAR(20),
    last_name VARCHAR(20),
    person_id varchar(10),
    PRIMARY KEY(person_id));
CREATE INDEX IF NOT EXISTS person_id_index on Person(person_id);
CREATE INDEX IF NOT EXISTS person_last_name_index on Person(last_name);

data.sql

INSERT INTO Person(person_id,first_name,last_name) VALUES('ABCDE12345','Jane','Doe');

Error log错误日志

018-02-03 23:12:33.916  INFO 88786 --- [           main] com.springboot.rest.PersonDaoTest       : Started PersonDaoTest in 336.053 seconds (JVM running for 336.71)
2018-02-03 23:12:34.023  INFO 88786 --- [           main] o.s.jdbc.datasource.init.ScriptUtils     : Executing SQL script from class path resource [schema.sql]
2018-02-03 23:12:34.023  INFO 88786 --- [           main] o.s.jdbc.datasource.init.ScriptUtils     : Executed SQL script from class path resource [schema.sql] in 0 ms.
2018-02-03 23:12:34.023  INFO 88786 --- [           main] o.s.jdbc.datasource.init.ScriptUtils     : Executing SQL script from class path resource [data.sql]
2018-02-03 23:12:34.037  WARN 88786 --- [           main] o.s.test.context.TestContextManager      : Caught exception while allowing TestExecutionListener [org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@5c33f1a9] to process 'before' execution of test method [public void com.springboot.rest.PersonDaoTest.testCreatePerson() throws java.lang.Exception] for test instance [com.springboot.rest.PersonDaoTest@577f9dfd]

org.springframework.jdbc.datasource.init.ScriptStatementFailedException:
 Failed to execute SQL script statement #1 of class path resource [data.sql]: 
INSERT INTO Person(person_id,first_name,last_name) VALUES('ABCDE12345','Jane','Doe'); 
nested exception is org.h2.jdbc.JdbcSQLException:
 Unique index or primary key violation: "PRIMARY_KEY_8 ON 
   PUBLIC.PERSON(PERSON_ID) VALUES ('ABCDE12345', 1)"; SQL statement:
INSERT INTO Person(person_id,first_name,last_name) VALUES('ABCDE12345','Jane','Doe') [23505-196]
    at org.springframework.jdbc.datasource.init.ScriptUtils.executeSqlScript(ScriptUtils.java:491) ~[spring-jdbc-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.jdbc.datasource.init.ResourceDatabasePopulator.populate(ResourceDatabasePopulator.java:238) ~[spring-jdbc-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.jdbc.datasource.init.DatabasePopulatorUtils.execute(DatabasePopulatorUtils.java:48) ~[spring-jdbc-4.3.12.RELEASE.jar:4.3.12.RELEASE]
. . . .
. . . . 
. . . . 
. . . .
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:207) [.cp/:na]
Caused by: org.h2.jdbc.JdbcSQLException: Unique index or primary key violation: "PRIMARY_KEY_8 ON PUBLIC.PERSON(PERSON_ID) VALUES ('ABCDE12345', 1)"; SQL statement:
INSERT INTO Person(person_id,first_name,last_name) VALUES('ABCDE12345','Jane','Doe') [23505-196]

application.properties

server.contextPath=/rest
spring.h2.console.enabled=true
spring.h2.console.path=/rest/h2

spring.datasource.url=jdbc:h2:file:./rest
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=true

I suppose your application at startup tries to add a record to the database with person_id = ABCDE12345 and you're getting the exception because such record already exists.我想您的应用程序在启动时尝试使用person_id = ABCDE12345将记录添加到数据库中,并且您收到异常,因为此类记录已存在。

PRIMARY KEY(person_id) in your schema adds a constraint that makes sure only unique values are present in person_id column.架构中的PRIMARY KEY(person_id)添加了一个约束,以确保person_id列中只存在唯一值。

With this constraint you'll be getting Unique index or primary key violation error each time you add a record to the database with non-unique record_id .使用此约束,每次向数据库添加非唯一record_id记录时,您都会收到Unique index or primary key violation错误。

As Oleg pointed out in comments, H2 is in memory database causing data to be already present leading to pk constraint exception.正如 Oleg 在评论中指出的那样,H2 在内存数据库中,导致数据已经存在,从而导致 pk 约束异常。

A simple task you can perform is to add DROP IF EXISTS statement in schema.sql so that any data existing is removed on every restart.您可以执行的一项简单任务是在 schema.sql 中添加 DROP IF EXISTS 语句,以便在每次重新启动时删除任何现有数据。 But make sure you use it for testing purpose only and remove it before moving to production.但请确保仅将其用于测试目的,并在投入生产之前将其删除。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM