I know there have been discussions wrt to dbunit here. I have read most of them but I cant seem to find a solution to my problem.
I have set up hibernate and spring. I am doing TDD so I had to wire up a proper DAO testing framework before writing code. Dbunit came to mind and I got to setting it up. Here is 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>
All seems well until i try to wire up some code using a base class that loads the dataset. Here is my code:
@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;
}
As soon as it hits the DatabaseOperation.CLEAN_INSERT.execute(connection, testDataset);
it throws the following exception:
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)
I have all the hibernate mapping files in place and the database is already set up with no data. Funny thing (or annoying thing depending on how you look at it) is that if I change the order of the tables in the dataset, the missingtableexception complains of another table... either user, reservation or status.
Any suggestions on what I might be doing wrong?
DBUnit will not create database tables for you because it has limited information from the dataset xml to create the intended database schema.
When used in tandem with hibernate, it will require proper hbm mapping files for every pojo (that you are trying to map to the in memory test database tables), which is ultimately used in the tests. Without the mapping files, you will get the org.dbunit.dataset.NoSuchTableException: Did not find table 'xxx' in schema 'yyy'
.
Also, a valid hibernate.cfg.xml is required, correctly configured with all the hibernate mapping files.
You can delegate the database creation to hibernate by setting this property hibernate.hbm2ddl.auto=create-drop
in your properties file.
The error message is a little misleading. Should probably contain more information to the effect of missing hibernate mapping files -- but this is a discussion on the DBunit wiki.