我在 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/