Java 如何调试hibernate.hbm2ddl.import_文件值与hsqldb组合的处理?

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配置中,我将设置

在我正在进行的一个Java项目中,我为我们的单元测试做了以下设置:

  • 我使用Spring测试MVC、
    @RunWith(SpringJUnit4ClassRunner.class)
    @WebAppConfiguration
    来运行单元测试,并使用
    webAppContextSetup(webApplicationContext)
    来测试应用程序,创建一个
    MockMvc
    实例
  • 我有一个Hibernate配置来设置内存中的HSQLDB,所有表都是基于@Entity类创建的
  • 在Hibernate配置中,我将设置
    Hibernate.hbm2ddl.import_files
    属性以加载带有sql语句的文件
    import.sql
    ,以填充(内存中)数据库
现在,我已经确认了上述所有工作:

  • 测试可以成功地从内存数据库中插入/检索
  • 根据各种测试的确认,执行
    import.SQL
    中的SQL语句
现在的问题是:我在import.sql中添加的语句出现的错误似乎没有在任何地方报告,也没有任何错误发生的迹象。相反,后面的语句不会执行。(我已经通过测试证实了这一点。)

是否有任何方式或地点,这些错误的报告,我显然不知道?是否有其他Hibernate属性

摘自hibernate测试配置:

    <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());
}