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

Java 在Spring引导应用程序中尝试将行插入H2 db时出现主键冲突异常,java,spring-boot,h2,Java,Spring Boot,H2,我正在尝试创建一个Spring引导应用程序来执行CRUD操作。但当我启动应用程序时,它会以异常终止。我不知道我做错了什么。这是我的DDL和DML。我不知道 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

我正在尝试创建一个Spring引导应用程序来执行CRUD操作。但当我启动应用程序时,它会以异常终止。我不知道我做错了什么。这是我的DDL和DML。我不知道

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);
INSERT INTO Person(person_id,first_name,last_name) VALUES('ABCDE12345','Jane','Doe');
data.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);
INSERT INTO Person(person_id,first_name,last_name) VALUES('ABCDE12345','Jane','Doe');
错误日志

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

我假设您的应用程序在启动时尝试向数据库中添加一条带有
person\u id
=
ABCDE12345
的记录,您得到了异常,因为这样的记录已经存在

模式中的主键(person\u id)
添加了一个约束,确保在
person\u id
列中只存在唯一的值


使用此约束,每次使用非唯一的
record\u id
将记录添加到数据库时,都会出现
唯一索引或主键冲突
错误

正如Oleg在评论中指出的,H2在内存数据库中,导致数据已经存在,导致pk约束异常


您可以执行的一个简单任务是在schema.sql中添加DROP IF EXISTS语句,以便在每次重新启动时删除所有现有数据。但是,请确保您仅将其用于测试目的,并在转入生产之前将其删除。

我猜您已经多次执行了该脚本,您的数据库可能已经有一条带有pk“ABCDE12345”的记录。因此,请检查您的数据库您的
spring.datasource.url
?验证您使用的是内存中的数据库。@Oleg更新了文章。您使用的是持久数据库,您希望它如何工作?在第一次运行它之后,您的
Person
表已经填充,再次尝试插入相同的数据,并且可能会出现主键冲突。尝试用
jdbc:h2:mem:rest
替换它。在我的例子中,schema.sql&data.sql文件已经存在于src/main/resource下,并且在src/test/resources下添加了引起问题的相同文件。因此,基本上,对于测试,src/main/resources下的文件将首先应用。