我正在尝试使用嵌入式数据库运行spring boot应用程序。在bean的初始化期间(由于某种原因?)我的表创建脚本被调用两次而第二次调用失败,其中"表已经存在"错误。下面是我的代码,可能是什么问题。
@Configuration
public class AppConfig {
private static final Logger LOG = LoggerFactory.getLogger(AppConfig.class);
private static EmbeddedDatabase dataSource;
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new DbPlaceholderConfigurer(dataSource());
}
@Bean
public static EmbeddedDatabase dataSource() {
if(dataSource == null) {
EmbeddedDatabaseBuilder databaseBuilder = new EmbeddedDatabaseBuilder();
databaseBuilder.addScript("classpath:schema.sql");
//databaseBuilder.setName("test");
databaseBuilder.setType(EmbeddedDatabaseType.H2);
EmbeddedDatabase build = databaseBuilder.build();
initPopulate(build);
dataSource = build;
}
return dataSource;
}
private static void initPopulate(EmbeddedDatabase embeddedDatabase) {
try {
Connection connection = embeddedDatabase.getConnection();
PreparedStatement prepareStatement;
prepareStatement = connection.prepareStatement("INSERT INTO Settings VALUES (?,?,?)");
prepareStatement.setInt(1, 1);
prepareStatement.setString(2, "testKey");
prepareStatement.setString(3, "testVal");
prepareStatement.executeUpdate();
connection.close();
} catch (SQLException e) {
LOG.error("Error ", e);
}
}
}
错误日志如下:
Caused by: org.h2.jdbc.JdbcSQLException: Table "SETTINGS" already exists; SQL statement:
CREATE TABLE Settings( id INT PRIMARY KEY, testKey VARCHAR(100), testValue VARCHAR(100) ) [42101-192]
注意:我可以通过设置以下属性来成功启动我的应用程序,但我真的很好奇为什么spring会两次调用表创建脚本。
spring.datasource.continue-on-error=true
注2:表创建脚本(schema.sql)如下所示:
create table contacts (
id identity,
firstname varChar(30) not null,
lastName varChar(30) not null,
phoneNumber varChar(20),
emailAddress varChar(50)
);
答案 0 :(得分:6)
我发现当我的 src / main / resources 中包含H2 schema.sql 和 data.sql 文件时,就会发生这种情况目录,也在我的 DatabaseConfig :
中引用@Bean
public DataSource embeddedDataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.addScript("classpath:schema.sql")
.addScript("classpath:data.sql")
.build();
}
我正在 DatabaseConfig 类中初始化内存数据库,然后Spring Boot尝试根据its configuration rules加载相同的数据。
要摆脱错误,请从 dataSource()中删除 schema.sql 和 data.sql 。
@Bean
public DataSource embeddedDataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2).build();
}
答案 1 :(得分:1)
您可以替换数据库初始化代码。 Spring Boot
提供开箱即用的功能。
以下属性应该给你一个想法:
spring.datasource.initialize=true # Populate the database using 'data.sql'.
spring.datasource.separator=; # Statement separator in SQL initialization scripts.
spring.datasource.sql-script-encoding= # SQL scripts encoding.
请参阅Spring Boot
documentation中的其他媒体资源。