単体テストに H2 データベースを使用しようとしています。私の実際のデータベースはMYSqlなので、H2でMYSQL方言を使用しています。hbm ファイルが読み込まれると、問題が発生するようです。H2またはHibernateがテーブルを変更しようとすると、外部キー/関連付けがうまくいかなくなります。
DB スクリプト:
DROP SCHEMA IF EXISTS `amr` ;
CREATE SCHEMA IF NOT EXISTS `amr`;
-- -----------------------------------------------------
-- Table `amr`.`classA`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `amr`.`classA` ;CREATE TABLE IF NOT EXISTS `amr`.`classA` (
`classA_id` INT(11) NOT NULL ,
`name` VARCHAR(56) NOT NULL ,
PRIMARY KEY (`classA_id`) );
-- -----------------------------------------------------
-- Table `amr`.`classB`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `amr`.`classB` ;CREATE TABLE IF NOT EXISTS `amr`.`classB` (
`classB_id` INT(11) NOT NULL ,
`name` VARCHAR(45) NOT NULL ,
`classA_id` INT(11) NOT NULL ,
PRIMARY KEY (`classB_id`) ,
INDEX `fk_classB_service_provider_classA1` (`classA_id` ASC) ,
CONSTRAINT `fk_classB_service_provider_classA1`
FOREIGN KEY (`classA_id` )
REFERENCES `amr`.`classA` (`classA_id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION);
私が受け取る例外:
09-11 08:46:33 jdbc[2]: exception
org.h2.jdbc.JdbcSQLException: Column "FOREIGN" not found; SQL statement:
alter table amr.classB drop foreign key FKAF0F85CABD96B12B [42122-168]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:329)
at org.h2.message.DbException.get(DbException.java:169)
at org.h2.message.DbException.get(DbException.java:146)
at org.h2.table.Table.getColumn(Table.java:605)
at org.h2.command.Parser.parseAlterTable(Parser.java:4874)
at org.h2.command.Parser.parseAlter(Parser.java:4315)
at org.h2.command.Parser.parsePrepared(Parser.java:306)
at org.h2.command.Parser.parse(Parser.java:279)
at org.h2.command.Parser.parse(Parser.java:251)
at org.h2.command.Parser.prepareCommand(Parser.java:217)
at org.h2.engine.Session.prepareLocal(Session.java:415)
at org.h2.engine.Session.prepareCommand(Session.java:364)
at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1109)
at org.h2.jdbc.JdbcStatement.executeUpdateInternal(JdbcStatement.java:121)
at org.h2.jdbc.JdbcStatement.executeUpdate(JdbcStatement.java:110)
at org.hibernate.tool.hbm2ddl.SchemaExport.execute(SchemaExport.java:421)
at org.hibernate.tool.hbm2ddl.SchemaExport.drop(SchemaExport.java:396)
at org.hibernate.tool.hbm2ddl.SchemaExport.execute(SchemaExport.java:269)
at org.hibernate.tool.hbm2ddl.SchemaExport.create(SchemaExport.java:219)
at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:370)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1842)
at org.springframework.orm.hibernate3.LocalSessionFactoryBean.newSessionFactory(LocalSessionFactoryBean.java:860)
at org.springframework.orm.hibernate3.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:779)
at org.springframework.orm.hibernate3.AbstractSessionFactoryBean.afterPropertiesSet(AbstractSessionFactoryBean.java:188)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1514)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1452)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:567)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:103)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:1)
at org.springframework.test.context.support.DelegatingSmartContextLoader.loadContext(DelegatingSmartContextLoader.java:228)
at org.springframework.test.context.TestContext.loadApplicationContext(TestContext.java:124)
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:148)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:321)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:211)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:288)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:290)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
09-11 08:46:33 jdbc[2]: exception
org.h2.jdbc.JdbcSQLException: Syntax error in SQL statement "ALTER TABLE AMR.CLASSB ADD INDEX FKAF0F85CABD96B12B (CLASSA_ID),[*] ADD CONSTRAINT FKAF0F85CABD96B12B FOREIGN KEY (CLASSA_ID) REFERENCES AMR.CLASSA (ID) "; SQL statement:
alter table amr.classB add index FKAF0F85CABD96B12B (classA_id), add constraint FKAF0F85CABD96B12B foreign key (classA_id) references amr.classA (id) [42000-168]
09-11 08:46:34 jdbc[2]: exception
org.h2.jdbc.JdbcSQLException: Column "FOREIGN" not found; SQL statement:
alter table amr.classB drop foreign key FKAF0F85CABD96B12B [42122-168]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:329)
at org.h2.message.DbException.get(DbException.java:169)
at org.h2.message.DbException.get(DbException.java:146)
at org.h2.table.Table.getColumn(Table.java:605)
at org.h2.command.Parser.parseAlterTable(Parser.java:4874)
at org.h2.command.Parser.parseAlter(Parser.java:4315)
at org.h2.command.Parser.parsePrepared(Parser.java:306)
at org.h2.command.Parser.parse(Parser.java:279)
at org.h2.command.Parser.parse(Parser.java:251)
at org.h2.command.Parser.prepareCommand(Parser.java:217)
at org.h2.engine.Session.prepareLocal(Session.java:415)
at org.h2.engine.Session.prepareCommand(Session.java:364)
at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1109)
at org.h2.jdbc.JdbcStatement.executeUpdateInternal(JdbcStatement.java:121)
at org.h2.jdbc.JdbcStatement.executeUpdate(JdbcStatement.java:110)
at org.hibernate.tool.hbm2ddl.SchemaExport.execute(SchemaExport.java:421)
at org.hibernate.tool.hbm2ddl.SchemaExport.drop(SchemaExport.java:396)
at org.hibernate.tool.hbm2ddl.SchemaExport.execute(SchemaExport.java:269)
at org.hibernate.tool.hbm2ddl.SchemaExport.drop(SchemaExport.java:229)
at org.hibernate.impl.SessionFactoryImpl.close(SessionFactoryImpl.java:959)
at org.springframework.orm.hibernate3.AbstractSessionFactoryBean.destroy(AbstractSessionFactoryBean.java:228)
at org.springframework.orm.hibernate3.LocalSessionFactoryBean.destroy(LocalSessionFactoryBean.java:899)
at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:211)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:498)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:474)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:442)
at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1066)
at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1040)
at org.springframework.context.support.AbstractApplicationContext$1.run(AbstractApplicationContext.java:958)
hbm マッピング:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping default-access="field">
<class name="ClassA" table="classA">
<id name="id" type="long">
<column name="id"/>
</id>
<property name="name" type="string">
<column name="name" length="56" not-null="true"/>
</property>
<set name="classBs" table="classB" inverse="true" lazy="true" fetch="select">
<key>
<column name="classA_id" not-null="true"/>
</key>
<one-to-many class="ClassB"/>
</set>
</class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping default-access="field">
<class name="ClassB" table="classB">
<id name="id" type="long">
<column name="id"/>
</id>
<property name="name" type="string">
<column name="name" length="56" not-null="true"/>
</property>
<many-to-one name="classA" class="ClassA" fetch="select">
<column name="classA_id" not-null="true"/>
</many-to-one>
</class>
</hibernate-mapping>
H2 URL:
jdbc:h2:~/db/amr_test;MODE=MYSQL;INIT=create schema if not exists test_db\\;runscript from 'classpath:amr_test_ddl.sql';DB_CLOSE_ON_EXIT=FALSE
-------------------編集/発見された問題--------------------------- -------
ほとんどゼロからやり直し、すべてを再評価した後、コンテキスト ファイルに以下のプロパティを不適切に追加したことがわかりました。
作成ドロップ
私のH2コンテキスト構成に案内したフォーラムの1つで、「セッションが閉じた後にスキーマをドロップする」ため、それを使用することを指摘しました。
したがって、このプロパティに関する私の無知は、教訓を学びました。
@Thomas Mueller - この件に関してお時間とご協力をいただき、誠にありがとうございます。