8 java spring dbunit hibernate
我知道dbunit已经在这里进行了讨论.我已经阅读了大部分内容,但我似乎无法找到解决问题的方法.
我已经设置了hibernate和spring.我正在做TDD所以我必须在编写代码之前连接一个正确的DAO测试框架.Dbunit浮现在脑海中,我必须设置它.这是ma testdataset.xml
<?xml version='1.0' encoding='UTF-8'?>
<dataset>
<table name="status">
<column>statusId</column>
<column>status</column>
<row>
<value>0</value>
<value>Available</value>
</row>
</table>
<table name="user">
<column>userId</column>
<column>firstName</column>
<column>lastName</column>
<column>username</column>
<column>password</column>
<column>email</column>
<row>
<value>0</value>
<value>system</value>
<value>admin</value>
<value>admin</value>
<value>admin</value>
<value>admin@ccbs.com</value>
</row>
</table>
<table name="reservation">
<column>reservationId</column>
<column>userId</column>
<column>reservationDate</column>
<column>startDate</column>
<column>endDate</column>
<column>statusId</column>
<row>
<value>0</value>
<value>0</value>
<value>2011-02-20 12:46:00.0</value>
<value>2011-03-01 12:00:00.0</value>
<value>2011-04-01 12:00:00.0</value>
<value>0</value>
</row>
</table>
</dataset>
Run Code Online (Sandbox Code Playgroud)
一切似乎都很好,直到我尝试使用加载数据集的基类连接一些代码.这是我的代码:
@Transactional
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:test-applicationContext.xml" })
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
public class BaseContextSensitiveTest {
@BeforeClass
public static void setUpDatabase() throws Exception {
URL file = getInitalDatasetURL();
testDataset = createDataset(file);
}
@Before
public void init() throws Exception {
log.info("Initializing Data Set");
connection = createDBUnitConnection();
DatabaseOperation.CLEAN_INSERT.execute(connection, testDataset);
}
private static URL getInitalDatasetURL() throws FileNotFoundException {
URL file = ClassLoader.getSystemResource(TEST_DATASET_LOCATION);
if (file == null) {
throw new FileNotFoundException("Unable to find '"
+ TEST_DATASET_LOCATION + "' in the classpath");
}
return file;
}
private static IDataSet createDataset(URL file) throws IOException,
DataSetException {
return new XmlDataSet(file.openStream());
}
private IDatabaseConnection createDBUnitConnection()
throws DatabaseUnitException, SQLException {
Connection connection = getConnection();
IDatabaseConnection dbUnitConn = new DatabaseConnection(connection);
// use the hsql datatypefactory so that boolean properties work
// correctly
DatabaseConfig config = dbUnitConn.getConfig();
config.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY,
new HsqldbDataTypeFactory());
return dbUnitConn;
}
Run Code Online (Sandbox Code Playgroud)
一旦它命中DatabaseOperation.CLEAN_INSERT.execute(connection, testDataset);它就会抛出以下异常:
org.dbunit.dataset.NoSuchTableException: Did not find table 'USER' in schema 'null'
at org.dbunit.database.DatabaseTableMetaData.<init>(DatabaseTableMetaData.java:142)
at org.dbunit.database.DatabaseDataSet.getTableMetaData(DatabaseDataSet.java:290)
at org.dbunit.operation.DeleteAllOperation.execute(DeleteAllOperation.java:109)
at org.dbunit.operation.CompositeOperation.execute(CompositeOperation.java:79)
at com.cottage.test.BaseContextSensitiveTest.init(BaseContextSensitiveTest.java:64)
Run Code Online (Sandbox Code Playgroud)
我有所有的hibernate映射文件,数据库已经设置好没有数据.有趣的事情(或者令人烦恼的事情取决于你如何看待它)是如果我改变数据集中表格的顺序,则missingtableexception会抱怨另一个表格...用户,预订或状态.
关于我可能做错什么的任何建议?
loy*_*own 12
我也遇到了同样的错误,上面接受的修复并没有解决我的问题.但是我能够找到解决方案.
我的设置包括DBUnit(2.4),EclipseLink(2.1)作为我的JPA提供程序,Postgres作为我的后端数据库.此外,在我的场景中,我没有丢弃并为每次测试运行重新创建表.我的测试数据已经存在.我知道不好的做法,但更多的是测试/原型设计方案.下面的代码说明了用于解决问题的DBUnit配置.
54 // ctx represents a spring context
55 DataSource ds = (DataSource)ctx.getBean("myDatasourceBean");
56 Connection conn = DataSourceUtils.getConnection(ds);
57 IDatabaseConnection dbUnitConn = new DatabaseConnection(conn, "public");
58 DatabaseConfig dbCfg = dbUnitConn.getConfig();
59 dbCfg.setFeature(DatabaseConfig.FEATURE_CASE_SENSITIVE_TABLE_NAMES, Boolean.TRUE);
60 IDataSet dataSet = new FlatXmlDataSet(ClassLoader.getSYstemResourceAsStream("mydbunitdata.xml"));
61 DatabaseOperation.REFRESH.execute(dbUnitConn, dataSet);
Run Code Online (Sandbox Code Playgroud)
上面代码中的两件事情解决了我的问题.首先,我需要定义DBUnit应该使用的模式.这是在上面第57行完成的.设置新的DatabaseConnection时,如果模式不为null,则应传入模式("public").
其次,我需要DBUnit对数据库表名称区分大小写.在我的DBUnit xml文件("mydbunitdata.xml")中,表名都是小写,就像它们在数据库中一样.但是,如果您不告诉DBUnit使用区分大小写的表名,它会查找Postgres不喜欢的大写表名.因此,我需要在DBUnit中设置区分大小写的功能,这在第59行完成.
小智 8
DBUnit不会为您创建数据库表,因为它具有来自数据集xml的有限信息以创建预期的数据库模式.
当与hibernate一起使用时,它将需要为每个pojo(您尝试映射到内存测试数据库表)中的正确hbm映射文件,这最终用于测试.如果没有映射文件,您将获得org.dbunit.dataset.NoSuchTableException: Did not find table 'xxx' in schema 'yyy'.
此外,需要一个有效的hibernate.cfg.xml,并使用所有hibernate映射文件正确配置.
您可以通过hibernate.hbm2ddl.auto=create-drop在属性文件中设置此属性来将数据库创建委派给hibernate .
错误消息有点误导.应该包含更多关于缺少hibernate映射文件效果的信息 - 但这是对DBunit wiki的讨论.
小智 8
删除dataset.xml文件中的第一行
<!DOCTYPE dataset>
并用它替换它
<?xml version='1.0' encoding='UTF-8'?>
否则DBUnit尝试从DTD文件加载db表模式,如果没有提供DTD,它将永远不会匹配任何表.使用普通的xml标头将导致DBUnit跳过此DTD - 表检查会引发您看到的错误.
你还必须做Grzegorz所做的事情,并通过包括hibernate为你的表做一个create-drop
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
要么
configuration.setProperty(Environment.HBM2DDL_AUTO, "create-drop");
| 归档时间: |
|
| 查看次数: |
34300 次 |
| 最近记录: |