我的应用程序仅从数据库中读取数据。没有创建/更新/删除操作。我试图将一个DB视图映射到JPA实体。此视图没有任何唯一ID。所以基本上每一行都是独特的。但是有些列的值可能为空。
现在的问题是:
1)我无法对数据库进行任何更改。它超出了我的范围。因此,无法使用新列添加视图以获取唯一ID。
2)我无法在没有主键的情况下创建JPA实体,因为它会抱怨它至少需要一个唯一的密钥。
3)如果我将@Id注释应用于所有列,那么它在逻辑上是有意义的,因为在我的情况下每一行都是唯一的。但在我的单元测试期间,HSQLDB会抱怨某些唯一列可能没有空值。
4)所以我决定推迟/禁用所有约束。因为在我的情况下,仅在使用DBUnit和HsqlDb创建内存模式期间考虑约束。
我尝试执行以下准备好的声明:
SET CONSTRAINTS ALL DEFERRED
但它失败了,错误:
Caused by: java.sql.SQLSyntaxErrorException: user lacks privilege or object not found: CONSTRAINTS
我不确定在初始数据库初始化期间如何禁用约束检查。我已经使用以下方法禁用了外键检查:
SET DATABASE REFERENTIAL INTEGRITY FALSE
它没有任何问题。如果您对如何禁用HsqlDb的所有约束检查有任何想法,请告诉我。
Jar版本:
DbUnit - 2.5.0
Junit - 4.10
HsqlDb 2.3.0
JDK - 1.7
更新1:
我将我的HsqlDb jar版本更新为2.3.4。我找到了以下参考资料:
http://hsqldb.org/doc/guide/dbproperties-chapt.html#N155DE
然后我尝试在最初的连接上执行这些语句:
SET DATABASE SQL UNIQUE NULLS { TRUE | FALSE }
但它没有帮助。
更新2:
我尝试使用以下方法将这些列显式设置为null:
ALTER TABLE T_NAME ALTER COLUMN C_NAME SET NULL
但我得错误说:
column is in primary key in statement [ALTER TABLE T_NAME ALTER COLUMN C_NAME SET NULL]
答案 0 :(得分:1)
两个可能有所帮助的想法:
将具有复合主键的JPA实体映射到现有数据库时,@ EmbeddedId是实体与多个@Id字段的正确方法:
此外,由于它以只读模式使用,因此请在@Id字段上使用可插入和可更新的@Column属性: @Column(insertable = false,updatable = false)
这些可能会导致JPA提供商在唯一性问题方面表现不同。
对于类似情况,我使用Apache Derby删除了参照完整性约束。我认为它也适用于HSQLDB。
您的问题并未说明您在何时发出删除约束命令,因此请确保在每次需要删除约束的测试开始时发出它们。
我写了一个" ConstraintManipulator"删除和恢复约束的类。需要约束禁用的测试称为正确的ConstraintManipulator在测试之前删除方法并在测试之后添加方法(仅需要关闭某些测试的特定约束并将其恢复以用于后续测试)。这些方法只是使用dbUnit配置的JDBC数据库连接发出DDL命令("添加约束..."," drop constraint ...")。
< / LI> 醇>答案 1 :(得分:0)
我首先使用以下方法删除主键来解决此问题:
ALTER TABLE T_NAME DROP PRIMARY KEY
然后使用以下方法删除各列的非空约束:
ALTER TABLE T_NAME ALTER COLUMN C_NAME SET NULL
正如杰夫在他的回答中所建议的,编写单独的类来禁用各个测试套件的约束是有意义的。