【发布时间】:2017-12-30 19:55:36
【问题描述】:
我正在使用 Apache Derby 作为内存中的模拟数据库,用于对使用 jOOQ 的一些与 MySQL 配合使用的代码进行单元测试。
生产数据库对某些字段使用枚举(这是给定的,超出了这个问题的范围 - 我知道枚举不好,但我现在不能更改这部分),所以 jOOQ 生成代码来处理枚举。
不幸的是,Derby 不支持枚举,当我尝试在 Derby 中创建数据库(来自 jOOQ SQL 生成器)时,我得到了错误。
我的解决方案是通过包装相关的 jOOQ 生成的枚举 Java 类来模拟枚举的用户定义类型。因此,例如,如果我在表 stuffs 中有一个枚举字段 kind,jOOQ SQL 生成器将创建 Derby 表创建 SQL,它讨论 stuffs_kind。
为了支持这一点,我创建了类 my.project.tests.StuffsKindDebyEnum,它包装了 jOOQ 生成的枚举类型 my.project.model.StuffsKind。然后,在运行 jOOQ 数据库创建 SQL 之前,我通过 Derby 运行以下 SQL:
CREATE TYPE stuffs_kind EXTERNAL NAME 'my.project.tests.StuffsKindDerbyEnum' LANGUAGE JAVA
当我使用 jOOQ 插入新记录时,jOOQ 生成的 SQL 看起来有点像这样:
insert into "schema"."stuffs" ("text", "kind")
values (cast (? as varchar(32672)), cast(? as stuffs_kind)
但是将字符串值绑定到 kind 参数(如预期的那样),它适用于 MySQL,但使用 Derby 我得到一个异常:
java.sql.SQLDataException: An attempt was made to get a data value of type
'"APP"."STUFFS_KIND"' from a data value of type 'VARCHAR'
在查看了解决此问题的各种方法(包括尝试将枚举视为简单的 VARCHAR)之后,并且在我放弃能够测试我的 jOOQ 使用代码之前,有没有办法让 Derby 获得“将“varchar 转换为用户定义的类型?如果可以放置一些可以处理该问题的 Java 代码,那将不是问题,因为我可以简单地执行 StuffsKind.valueOf(value) 将字符串转换为正确的枚举类型,但是在仔细阅读(非常少的)Derby 文档之后,我不能弄清楚它是否应该是可能的。
欢迎提出任何想法!
【问题讨论】:
-
一旦您开始使用供应商特定的功能,使用“内存模拟数据库”总是很痛苦。使用实际的 MySQL 数据库(例如在 Docker 中)进行集成测试怎么样?
-
除非我找到其他解决方案,否则我必须这样做,但我真的不想这样做,因为它会引起很多头痛(不能并行运行测试,痛苦设置过程等)。
-
另一种选择,也许是这个东西:github.com/vorburger/MariaDB4j。我还没有尝试过,但它看起来对我的用例很有趣。
-
为什么不能在 Docker 和/或 Testcontainers 或类似的设备上并行运行测试?设置过程有什么痛苦?
-
我已经查看了 Testcontainers,它看起来很有希望。如果我需要 Windows 支持,MariaDB4j 可能是一个更好的选择,但由于情况并非如此,我将尝试使用 Testcontainers 继续前进,但我也会尝试看看您下面的答案是否可以解决我的问题。跨度>