Java 如何调试hibernate.hbm2ddl.import_文件值与hsqldb组合的处理?
在我正在进行的一个Java项目中,我为我们的单元测试做了以下设置:Java 如何调试hibernate.hbm2ddl.import_文件值与hsqldb组合的处理?,java,spring,hibernate,hsqldb,spring-test-mvc,Java,Spring,Hibernate,Hsqldb,Spring Test Mvc,在我正在进行的一个Java项目中,我为我们的单元测试做了以下设置: 我使用Spring测试MVC、@RunWith(SpringJUnit4ClassRunner.class)和@WebAppConfiguration来运行单元测试,并使用webAppContextSetup(webApplicationContext)来测试应用程序,创建一个MockMvc实例 我有一个Hibernate配置来设置内存中的HSQLDB,所有表都是基于@Entity类创建的 在Hibernate配置中,我将设置
- 我使用Spring测试MVC、
和@RunWith(SpringJUnit4ClassRunner.class)
来运行单元测试,并使用@WebAppConfiguration
来测试应用程序,创建一个webAppContextSetup(webApplicationContext)
实例MockMvc
- 我有一个Hibernate配置来设置内存中的HSQLDB,所有表都是基于@Entity类创建的
- 在Hibernate配置中,我将设置
属性以加载带有sql语句的文件Hibernate.hbm2ddl.import_files
,以填充(内存中)数据库import.sql
- 测试可以成功地从内存数据库中插入/检索
- 根据各种测试的确认,执行
中的SQL语句import.SQL
<bean id="sessionFactory" name="mySessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.archive.autodetection">class,hbm</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.connection.driver_class">org.hsqldb.jdbcDriver</prop>
<prop key="hibernate.connection.username">sa</prop>
<prop key="hibernate.connection.password"></prop>
<prop key="hibernate.connection.url">jdbc:hsqldb:mem:myschema</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
<prop key="hibernate.hbm2ddl.import_files">configuration/test/import.sql</prop>
<prop key="hibernate.hbm2ddl.import_files_sql_extractor">org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor</prop>
<!-- when using type="yes_no" for booleans, the line below allow booleans in HQL expressions: -->
<prop key="hibernate.query.substitutions">true 'Y', false 'N'</prop>
</props>
</property>
</bean>
班级,哈佛商学院
org.hibernate.dialogue.hsql方言
真的
org.hsqldb.jdbcDriver
sa
jdbc:hsqldb:mem:myschema
创造
配置/test/import.sql
org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor
真“Y”,假“N”
并不是对您的问题的真正回答,而是处理测试数据库填充的替代方法
Spring中有一个名为jdbc
的XML名称空间,允许您在Spring上下文启动期间用初始数据预填充数据库。此外,它还可以报告SQL中的错误:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc.xsd">
<jdbc:initialize-database data-source="dataSource">
<jdbc:script location="org/mytestproject/schema-drop-hsqldb.sql" />
<jdbc:script location="org/mytestproject/schema-hsqldb.sql" />
<jdbc:script location="org/mytestproject/data-hsqldb.sql" />
</jdbc:initialize-database>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="validationQuery" value="${jdbc.validationQuery}"/>
</bean>
</beans>
您可以使用级别跟踪激活登录类org.hibernate.tool.hbm2ddl.SchemaExport 在调试级别记录了一些错误(例如,未找到文件):
我无法像@Julien Kroneg建议的那样,获取日志中的异常 但是我能够在方法
org.hibernate.tool.hbm2ddl.SchemaExport#importScript
的catch块中放置断点,其中trimmedSql
表示应用的每个SQL语句:
catch ( Exception e ) {
if (haltOnError) {
throw new ImportScriptException( "Error during statement execution (file: '"
+ namedReader.getName() + "'): " + trimmedSql, e );
}
exceptions.add(e);
LOG.unsuccessful(trimmedSql);
LOG.error(e.getMessage());
}
考虑到init脚本是静态的,而不是真正的业务数据,这可能就足够了,一旦您让它们工作起来,它们就有望继续工作。感谢您提供这种替代方案。当我实现它时,会发生一个关于不存在已用表的错误。是否该方法在Hibernate自动创建表之前执行import.sql?是的,add取决于Hibernate sessionFactory。在我的示例中,Spring直接在SQL中创建和删除表。不幸的是,我不得不在这里使用Hibernate的自动创建功能。。。无论如何,谢谢你,欢迎你提出进一步的建议!您是否在
初始化数据库bean中尝试了依赖于class='sessionFactory'
?对不起,我误读了您的评论!我的IDE告诉我(当我运行IDE时)这不是initializedatabase
标记的有效属性。我把它添加到错误的地方了吗?这是我使用的第二个最好的解决方案,直到我实现了一个最好的解决方案,即完全取消使用导入脚本。
catch ( Exception e ) {
if (haltOnError) {
throw new ImportScriptException( "Error during statement execution (file: '"
+ namedReader.getName() + "'): " + trimmedSql, e );
}
exceptions.add(e);
LOG.unsuccessful(trimmedSql);
LOG.error(e.getMessage());
}