我正在测试Spring Boot Batch应用程序。我正在使用一个内存中的H2 DB,该数据库想通过一些数据进行初始化,但是以Unique index or primary key violation: PRIMARY_KEY_7 ON ...
失败。
我尝试调整application.properties
,添加和删除
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.properties.hibernate.default_schema=AD1
还要调整spring.datasource.url
。
实体如下:
@Table(schema = "ad1",name = "Student")
public class Student {
@Id
@Column(name = "student_id")
private String studentId;
@Column(name = "student_name")
private String studentName;
@Column(name = "favourite_subject")
private String favouriteSubject;
@Column(name = "enrollment_date")
private LocalDate enrollmentDate;
}
请注意,schema
属性已设置为ad1
data-h2.sql
中的 src/test/resources
如下:
Insert into ad1.Student (student_id,student_name,favourite_subject,enrollment_date) values ('1151AB26','John','Math',to_date('01-JAN-19','DD-MON-RR'));
同样在application.properties
中的 src/test/resources
如下:
spring.datasource.platform=h2
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;MODE=Oracle;INIT=CREATE SCHEMA IF NOT EXISTS AD1
spring.datasource.username=sa
spring.datasource.password=sa
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.properties.hibernate.default_schema=AD1
spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
spring.batch.job.enabled=false
要注意的是spring.datasource.url=jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;MODE=Oracle;INIT=CREATE SCHEMA IF NOT EXISTS AD1
。我必须将架构初始化为AD1
我正在使用黄瓜,所以我有一个黄瓜测试班:
@RunWith(Cucumber.class)
@CucumberOptions(features = "src/test/resources", plugin = { "pretty", "html:target/cucumber" })
public class CucumberTest {
}
最后但并非最不重要的Spring Boot测试类
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = StudentBatchApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ContextConfiguration
public abstract class SpringCucumberIntegrationTest {
发生的事情是,当我开始测试时,我得到以下信息:
Caused by: org.h2.jdbc.JdbcSQLException: Unique index or primary key violation: "PRIMARY_KEY_7 ON AD1.Student(student_id) VALUES ('1151AB26', 1)"; SQL statement:
Insert into AD1.Student (student_id,student_name,favourite_subject,enrollment_date) values ('1151AB26','John','Math',to_date('01-JAN-19','DD-MON-RR')) [23505-197]
当我对此进行故障排除时,通过在初始化发生时放置一个断点,该过程在同一行运行两次:
( /* key:1 */ '1151AB26', 'John', 'Math', TIMESTAMP '2019-01-01 00:00:00')
( /* key:2 */ '1151AB26', 'John', 'Math', TIMESTAMP '2019-01-01 00:00:00')
此后,它将引发异常。
答案 0 :(得分:0)
正如我提到的,在故障排除过程中,我注意到data-h2.sql
中的一行被以某种方式运行了两次,因此出现了唯一索引冲突。进一步进行故障排除,我追溯到该过程中加载数据脚本的位置(即data-h2.sql
),并注意到它两次加载了此脚本。一次进入target\classes\data-h2.sql
,一次进入target\test-classes\data-h2.sql
。老实说,我不知道为什么将此脚本文件复制到target\classes\data-h2.sql
。
最后,我发现这是一个月食问题。当我使用命令行mvn clean test
运行测试时。测试运行完美,但是当我使用Eclipse Run As -> JUnit Test
运行测试时,我会遇到此问题。由于某种原因,每当我在Eclipse Project -> Clean
中清理应用程序时,它都会将所有资源文件从src/main/resources
和src/test/resources
复制到target\classes
中。我要做的是将以下行添加到我的.classpath
文件中。
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>