JUnit / HSQLDB:使用HSQLDB进行测试时如何解决Oracle语法错误(没有特权和/或没有DUAL对象)

时间:2011-01-07 18:21:22

标签: oracle hibernate jdbc junit hsqldb

我有DAO代码,其中包含一些具有Oracle特定语法的JDBC,例如:

select count(*) cnt from DUAL 
where exists (select null from " + TABLE_NAME + "
              where LOCATION = '" + location + "')")

我正在使用内存中的HSQLDB数据库对此DAO方法运行JUnit测试。显然,DUAL表是特定于Oracle的,并且在运行测试时会导致错误:

org.springframework.jdbc.BadSqlGrammarException: StatementCallback; 
    bad SQL grammar [select count(*) cnt from DUAL where exists 
                    (select null from ESRL_OBSERVATIONS where LOCATION = '/path1')];
nested exception is java.sql.SQLException: user lacks privilege or object 
    not found: DUAL

任何人都可以建议我可以做些什么来解决这个问题吗?我正在使用Hibernate来创建模式 - 也许我可以在Hibernate属性中创建一个设置来支持Oracle样式语法?

4 个答案:

答案 0 :(得分:7)

如果将Hibernate 3.6与HSQLDB 2.0.1或更高版本一起使用,则可以在连接URL上使用连接属性sql.syntax_ora=true。这使DUAL表与其他一些Oracle特定语法一起使用。

对于主要属性未涵盖的行为,您可能还需要一些连接属性。看到: http://hsqldb.org/doc/2.0/guide/management-chapt.html#mtc_compatibility_oracle

答案 1 :(得分:4)

也可以通过SQL命令

启用HSQL“Oracle样式语法”
SET DATABASE SQL SYNTAX ORA TRUE

12.30。它是fredt答案中建议的sql.syntax_ora=true属性的替代品。在某些情况下可能更实用:在HSQL数据库启动后,可以通过JDBC设置标志。

答案 2 :(得分:2)

在HSQLDB数据库中创建一个名为DUAL的表,其中包含一列“DUMMY”。插入一行,值为'X'。

答案 3 :(得分:0)

这是一个旧线程,但可以使用自定义URL来设置oracle方言。我创建了一个带有更新url的自定义数据源工厂,并在初始化DB时注入了相同的内容。

//Custom class
public class CusstomSimpleDriverDataSourceFactory implements DataSourceFactory {

    private final SimpleDriverDataSource dataSource = new SimpleDriverDataSource();

    @Override
    public ConnectionProperties getConnectionProperties() {
        return new ConnectionProperties() {
            @Override
            public void setDriverClass(Class<? extends Driver> driverClass) {
                dataSource.setDriverClass(driverClass);
            }

            @Override
            public void setUrl(String url) {
                System.out.println("Existing url: " + url);
                String newUrl = url+";sql.syntax_ora=true";
                System.out.println("New url: " + newUrl);
                dataSource.setUrl(newUrl);
            }

            @Override
            public void setUsername(String username) {
                dataSource.setUsername(username);
            }

            @Override
            public void setPassword(String password) {
                dataSource.setPassword(password);
            }
        };
    }

    @Override
    public DataSource getDataSource() {
        return this.dataSource;
    }

}

Then in the configuration you can use
    public DataSource dataSource() {
        return new EmbeddedDatabaseBuilder()
              .setType(EmbeddedDatabaseType.HSQL)
              .setDataSourceFactory(new CusstomSimpleDriverDataSourceFactory())
              .addScript("ddl_script") 
              .addScript("dml_script")
              .build();
    }