我在Spring中使用HSQL
數據庫時有一些不確定的行爲。有時,sequence
會生成兩次,並且DataSource
初始化會因此而失敗。HSQL數據庫偶爾會執行兩次schema.sql
奇怪的是,如果失敗,它總是從試圖讀取不存在的數據庫條目的測試中。讀取現有條目的其他測試不會失敗。
我真的不明白我做錯了什麼,爲什麼發生這種情況。
HSQLDB
版本2.3.2
UPDATE: 我已刪除序列完全,現在我再次,偶爾得到錯誤正在創建兩倍表憑證。
這裏是我的配置:
@EnableJpaRepositories
@EnableTransactionManagement
@Configuration
@Profile("test")
public class TestDatabaseConfig {
@Bean
@Primary
public EntityManagerFactory entityManagerFactory() throws ClassNotFoundException {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(false);
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan(ENTITIES_PACKAGE);
factory.setDataSource(dataSource());
factory.afterPropertiesSet();
return factory.getObject();
}
@Bean
@Primary
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder().addDefaultScripts()
.setType(EmbeddedDatabaseType.HSQL)
.build();
}
@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) throws ClassNotFoundException {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(entityManagerFactory);
return txManager;
}
}
而且schema.sql文件:
CREATE SEQUENCE voucher_id_seq AS INTEGER START WITH 100 INCREMENT BY 1;
CREATE TABLE voucher (id INTEGER, code VARCHAR(64) NOT NULL UNIQUE, type VARCHAR(64) NOT NULL, state VARCHAR(64) NOT NULL, class_name VARCHAR(64), serial VARCHAR(64), consumption_user VARCHAR(255), creation_date TIMESTAMP DEFAULT current_timestamp, consumption_date TIMESTAMP, expiry_date TIMESTAMP)
data.sql:
-- VALID
INSERT INTO voucher (id, code, type, state, serial) VALUES (1,'success', '1', 'E', 'serial: 123');
--ALREADY CONSUMED
INSERT INTO voucher (id, code, type, state) VALUES (2,'used', '1', 'U');
-- DATE EXPIRED
INSERT INTO voucher (id, code, type, state, expiry_date) VALUES (3,'expired', '1', 'E', DATE '2014-12-12');
和錯誤跟蹤,在頂部,你可以看到序列有時會產生兩次:
引起:org.springframework.beans.BeanInstantiationException:無法實例化[javax.sql.DataSource]:工廠方法'dataSource'拋出異常;嵌套異常是org.springframework.jdbc.datasource.init.ScriptStatementFailedException:無法在資源類路徑資源[schema.sql]的第1行執行SQL腳本語句:CREATE SEQUENCE voucher_id_seq AS INTEGER START WITH 100 INCREMENT BY 1;嵌套異常是java.sql.SQLSyntaxErrorException:對象名已存在:語句中的VOUCHER_ID_SEQ [CREATE SEQUENCE voucher_id_seq AS INTEGER START WITH 100 INCREMENT BY 1] at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java: 189)〜[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)〜[spring-beans- 4.1.6.RELEASE.jar:4.1.6.RELEASE] ...省略了158個常用框架 引起的原因:org.springframework.jdbc.datasource.init.ScriptStatementFailedException:無法在資源類的第1行執行SQL腳本語句路徑資源[schema.sql]:CREATE SEQUENCE voucher_id_seq AS INTEGER START WITH 100 INCREMENT BY 1;嵌套異常是java.sql.SQLSyntaxErrorException:對象名已存在:語句中的VOUCHER_ID_SEQ [CREATE SEQUENCE voucher_id_seq AS INTEGER START WITH 100 INCREMENT BY 1] at org.springframework.jdbc.datasource.init.ScriptUtils.executeSqlScript(ScriptUtils.java: (資源數據庫管理器.java:208)〜[spring-jdbc- 4.0.9.RELEASE.jar:4.0.9.RELEASE] at org.springframework.jdbc.datasource.init.DatabasePopulatorUtils.execute(DatabasePopulatorUtils.java:49)〜[spring-jdbc-4.0.9.RELEASE.jar: 4.0.9.RELEASE] at org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactory.initDatabase(EmbeddedDatabaseFactory.java:159)〜[spring-jdbc-4.0.9.RELEASE.jar:4.0.9.RELEASE] at org.springframework.jdbc .datasource.embedded.EmbeddedDatabaseFactory.getDatabase(EmbeddedDatabaseFactory.java:132)〜[spring-jdbc-4.0.9.RELEASE.jar:4.0.9.RELEASE] at org.springframework.jdbc.datasource。embedded.EmbeddedDatabaseBuilder.build(EmbeddedDatabaseBuilder.java:251)〜[spring-jdbc-4.0.9.RELEASE.jar:4.0.9.RELEASE] at com.siemens.ott.TestDatabaseConfig.dataSource(TestDatabaseConfig.java:46) 〜[test-classes /:na] at com.siemens.ott.TestDatabaseConfig $$ EnhancerBySpringCGLIB $$ 6a150586.CGLIB $ dataSource $ 1()〜[spring-core-4.1.6.RELEASE.jar:na] at com .siemens.ott.TestDatabaseConfig $$ EnhancerBySpringCGLIB $$ 6a150586 $$ FastClassBySpringCGLIB $$ 125e7bce.invoke()〜[spring-core-4.1.6.RELEASE.jar:na] at org.springframework.cglib.proxy.MethodProxy。 invokeSuper(MethodProxy.java:228)〜[spring-core-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.context.annotation.ConfigurationClassEnhancer $ BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:309) 〜[spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE] at com.siemens.ott.TestDatabaseConfig $$ EnhancerBySpringCGLIB $$ 6a150586.dataSource()〜[spring-core-4.1.6.RELEASE.jar:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)〜[ na:1.8.0_45] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)〜[na:1.8.0_45] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)〜[na: 1.8.0_45] at java.lang.reflect.Method.invoke(Method.java:497)〜[na:1.8.0_45] at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java: 162)〜[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] ...忽略159個常用幀 引起:java.sql.SQLSyntaxErrorException:對象名已存在:VOUCHER_ID_SEQ in stat ement [CREATE SEQUENCE voucher_id_seq AS INTEGER START WITH 100 INCREMENT BY 1] at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)〜[hsqldb-2.3.2.jar:2.3.2] at org.hsqldb.jdbc .JDBCUtil.sqlException(Unknown Source)〜[hsqldb-2.3.2.jar:2.3.2] at org.hsqldb.jdbc.JDBCStatement.fetchResult(Unknown Source)〜[hsqldb-2.3.2.jar:2.3.2 ] at org.springframework.jdbc.datasource.init.ScriptUtils.executeSqlScript(ScriptUtils.java:[org.hsqldb.jdbc.JDBCStatement.execute(Unknown Source)〜[hsqldb-2.3.2.jar:2.3.2] ) 459)〜[彈簧JDBC-4.0.9.RELEASE.jar:4.0.9.RELEASE] ... 175個共同幀省略 所致:org.hsqldb.HsqlException:對象名已存在:VOUCHER_ID_SEQ