java - DbUnit-JdbcSQLException : Function "*" not found

标签 java sql-server user-defined-functions dbunit

我在 MS SQL Server 中有一个从 Java 代码调用的用户定义函数,在 H2 数据库中运行集成测试时该函数似乎未定义。你可以在 the previous question 找到我的代码.

测试代码:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {H2Config.class})
@TestExecutionListeners({
        DependencyInjectionTestExecutionListener.class,
        DbUnitTestExecutionListener.class,
        TransactionalTestExecutionListener.class
})
@TransactionConfiguration(defaultRollback = true)
public class TableDaoTest {

    @Autowired
    private TableDao tableDao;

    @Test
    @DatabaseSetup("/datasets/import.xml")
    public void testMethod01() {
        tableDao.getRecordsByGroup();
        ...

数据库模式由 Hibernate 自动生成。正如您所看到的,测试数据是由 DbUnit 使用 xml 数据集填充的。这个测试失败了,因为我的 MS SQL Server DB 中存在的函数在 H2 数据库中未定义。

应用程序日志:

Caused by: org.hibernate.exception.GenericJDBCException: could not prepare statement
    ...
Caused by: org.h2.jdbc.JdbcSQLException: Function "SAFE_MOD" not found; SQL statement:
    select table10_.id, table10_.value, ... from Table1 table10_ where table10_.group1=dbo.safe_mod(?, ?);
    ...

如何在 DbUnit 测试之前导入/创建函数?

最佳答案

H2数据库不支持用户定义的SQL函数。但是,在此数据库中,Java 函数也可以用作存储过程。

@SuppressWarnings("unused")
public class H2Function {
    public static int safeMod(Integer n, Integer divider) {
        if (divider == null) {
            divider = 5000;
        }

        return n % divider;
    }

}

注意,仅支持静态 Java 方法;类和方法都必须是公共(public)的。

Java 函数必须通过调用 CREATE ALIAS ... FOR 进行声明(在数据库中注册),然后才能使用:

CREATE ALIAS IF NOT EXISTS safe_mod DETERMINISTIC FOR "by.naxa.H2Function.safeMod";

该语句应该在任何测试之前执行,因此我决定将其放在连接初始化 SQL 中:

@Bean
public DataSource dataSource() {
    BasicDataSource dataSource = new BasicDataSource();

    dataSource.setDriverClassName("org.h2.Driver");
    dataSource.setUrl("jdbc:h2:mem:my_db_name");
    dataSource.setUsername("sa");
    dataSource.setPassword("");   
    dataSource.setConnectionInitSqls(Collections.singleton(
        "CREATE ALIAS IF NOT EXISTS safe_mod DETERMINISTIC FOR \"by.naxa.H2Function.safeMod\";"));

    return dataSource;
}

关于java - DbUnit-JdbcSQLException : Function "*" not found,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46408493/

相关文章:

java - Hibernate 5 : org. hibernate.MappingException: 未知实体

java - 玩数字编程挑战(在java中查找子数组的平均值)

java - 如何在 GUI 中出现另一个 JOptionPane 时关闭一个 JOptionPane

java - 是否可以使用 WireMock 将文件作为请求正文的一部分传递?

sql-server - 如果不存在 INSERT 事务,则 SQL Server 对 SELECT 进行 ROWLOCK

user-defined-functions - 在 UDF 中返回多个值

sql-server - 为什么 SQL 函数比 UDF 快

c++ - 用于加密/解密的 Firebird 数据库 UDF 不释放内存

sql - 连接和分组多个表

sql-server - SQL Server 为 -(连字符)后的字母转换大小写