Org.dbunit.dataset.NoSuchTableException: could not find table 'xxx' in schema 'null'

I know that discussions were discussed here. I have read most of them, but I cannot find a solution to my problem.

I set hibernation and spring. I am doing TDD, so before writing the code I had to plug in the proper DAO testing framework. Dbunit came to mind, and I got to it. 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> 

Everything seems good until I try to connect some code using a base class that loads a data set. 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 gets into 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 configured without data. The funny thing (or an annoying thing depending on how you look at it) is that if I change the order of the tables in the data set, the missing exception complains about another table ... user, reservation or status.

Any suggestions on what I might be doing wrong?

+8
source share
7 answers

DBUnit will not create database tables for you, as it has limited information from the xml dataset to create the intended database schema.

When used in tandem with sleep mode, you will need the appropriate hbm mapping files for each pojo (which you are trying to map to the memory test database tables) that is ultimately used in the tests. Without mapping files, you will get org.dbunit.dataset.NoSuchTableException: Did not find table 'xxx' in schema 'yyy' .

In addition, the correct hibernate.cfg.xml is required, correctly configured with all hibernate mapping files.

You can delegate the creation of a database to sleep by setting this hibernate.hbm2ddl.auto=create-drop property to your properties file.

The error message is a little misleading. There should probably be more information about the impact of missing hibernation mapping files - but this is a discussion in the DBunit database.

+8
source

I also encountered the same error, and the adopted fix above does not fix my problems. However, I was able to find a solution.

My setup consisted of DBUnit (2.4), EclipseLink (2.1) as my JPA provider, and Postgres as my backend database. Also, in my scenario, I did not drop or recreate the tables for each test run. My test data already exists. The bad practice that I know, but it was more like a testing / prototyping scenario. The code below shows the DBUnit configuration used to fix my problem.

 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); 

Two things in the code above fixed my problem. First I needed to determine the schema that DBUnit should use. This is done on line 57 above. When a new DatabaseConnection is installed, the schema ("public") must be passed if it is not null.

Secondly, I need DBUnit to be case sensitive in database table names. In my DBUnit xml file ("mydbunitdata.xml"), the table names have lowercase letters, as in the database. However, unless you specify that DBUnit uses case-sensitive table names, it searches for uppercase names that Postgres did not like. Therefore, I needed to set a case-sensitive function in DBUnit, which runs on line 59.

+12
source

delete the first line in the dataset.xml file

<!DOCTYPE dataset>

and replace it with

<?xml version='1.0' encoding='UTF-8'?>

otherwise DBUnit tries to load the db table schema from the DTD file, and if no DTD is provided, it will never match in any tables. Using a simple xml header will cause DBUnit to skip this check of the DTD table, which throws the error you see.

You must also do what Grzegorz did, and have hibernation to create a frame for your tables by enabling

<property name="hibernate.hbm2ddl.auto" value="create-drop"/>

or

configuration.setProperty(Environment.HBM2DDL_AUTO, "create-drop");

+8
source

Are database tables created in your database?

dbunit will not do this for you because it does not know the intended database structure. However, you can ask Hibernate to do this. Use the hbm2ddl flag, for example:

  <property name="hibernate.hbm2ddl.auto" value="create-drop"/> 

I could not find the main documentation for the flag, but if you were looking for it, you would get a lot of results, including. http://docs.jboss.org/ejb3/docs/reference/build/reference/en/html/entityconfig.html

+2
source

You may be interested in this. I also found this error and renamed my table in the hibernate.cfg.xml file from 'message' to 'MESSAGE', it was able to find the schema.

Let me know if this works for you too.

+1
source

I encountered the same error and had both objects in hibernate.cfg.xml, and I used hbm2ddl to generate tables, so I searched and found that in my object mapping there was a β€œPOSITION” field, which is a reserved term. When I changed it to "POS", the table was formed correctly.

You can check if your table is being generated by debugging the resultSet iteration in

org.dbunit.database.DatabaseDataSet.initialize ().

0
source

DbUnit classes take the default schema from the database. If the scheme you want to use is not the default scheme, you need to set the desired scheme inside the XML file and enable the recognition option for other schemes, see Solution below. I created it.

Example.xml - multiple schemas

 <?xml version='1.0' encoding='UTF-8'?> <dataset> <SCHEMA1.NAME_TABLE id="5" userName="1" /> <SCHEMA2.NAME_TABLE id="2" roleName="1" /> <dataset> <?xml version='1.0' encoding='UTF-8'?> <dataset> <PEOPLE.USER id="5" userName="1" /> <FUNCTIONS.ROLE id="2" roleName="1" /> <dataset> 

TEST CLASS

  @Before public void initialize() throws Exception{ //Insert data into database DatabaseOperation.CLEAN_INSERT.execute(getConnection(), getDataSet()); } @After public void cleanup() throws Exception{ //Clean up the database DatabaseOperation.DELETE_ALL.execute(getConnection(), getDataSet()); System.out.println("DELETADO COM SUCESSO!"); } private IDatabaseConnection getConnection() throws Exception{ // Get the database connection Connection con = dataSource.getConnection(); DatabaseMetaData databaseMetaData = con.getMetaData(); DatabaseConnection connection = new DatabaseConnection(con,databaseMetaData.getUserName().toUpperCase()); //Allow multiple schemas to be used connection.getConfig().setFeature(DatabaseConfig.FEATURE_QUALIFIED_TABLE_NAMES, true); return connection; } private IDataSet getDataSet() throws Exception{ //Get file to insert File file = new File("src/test/resources/Example.xml"); return new FlatXmlDataSet(file); } 
0
source

All Articles