Is there any way for DBUnit to automatically create tables?
Asked Answered
F

5

24

I just realized that DBUnit doesn't create tables by itself (see How do I test with DBUnit with plain JDBC and HSQLDB without facing a NoSuchTableException?).

Is there any way for DBUnit to automatically create tables from a dataset or dtd?

EDIT: For simple testing of an in-memory database like HSQLDB, a crude approach can be used to automatically create tables:

private void createHsqldbTables(IDataSet dataSet, Connection connection) throws DataSetException, SQLException {
    String[] tableNames = dataSet.getTableNames();

    String sql = "";
    for (String tableName : tableNames) {
      ITable table = dataSet.getTable(tableName);
      ITableMetaData metadata = table.getTableMetaData();
      Column[] columns = metadata.getColumns();

      sql += "create table " + tableName + "( ";
      boolean first = true;
      for (Column column : columns) {
        if (!first) {
          sql += ", ";
        }
        String columnName = column.getColumnName();
        String type = resolveType((String) table.getValue(0, columnName));
        sql += columnName + " " + type;
        if (first) {
          sql += " primary key";
          first = false;
        }
      }
      sql += "); ";
    }
    PreparedStatement pp = connection.prepareStatement(sql);
    pp.executeUpdate();
}

private String resolveType(String str) {
  try {
    if (new Double(str).toString().equals(str)) {
      return "double";
    }
    if (new Integer(str).toString().equals(str)) {
      return "int";
    }
  } catch (Exception e) {}

  return "varchar";
}
Floranceflore answered 7/10, 2009 at 12:25 Comment(0)
F
15

Not really. As the answer you linked points out, the dbunit xml files contain data, but not column types.

And you really don't want to do this; you risk polluting your database with test artifacts, opening up the possibility that production code will accidentally rely on tables created by the test process.

Needing to do this strongly suggests you don't have your db creation and maintenance process adequately defined and scripted.

Fathom answered 7/10, 2009 at 12:34 Comment(0)
C
4

No. You will have to execute an SQL script with the table definitions in.

As I posted in the other thread, the XML does not contain enough data to create a table. I guess you could do something scary like parse the values to attempt to work out what values it contains but that would be quite brittle. This differs from Hibernate in that annotated classes do contain a lot of information on how the database looks. Part in annotations and part in the Java types fields have.

http://www.dbunit.org/faq.html#ddl

Catchweight answered 7/10, 2009 at 12:30 Comment(0)
K
3

Spring Boot/ Spring JDBC can initialize a database with plain JDBC.

Spring JDBC has a DataSource initializer feature. Spring Boot enables it by default and loads SQL from the standard locations schema.sql and data.sql (in the root of the classpath). In addition Spring Boot will load the schema-${platform}.sql and data-${platform}.sql files (if present), where platform is the value of spring.datasource.platform, e.g. you might choose to set it to the vendor name of the database (hsqldb, h2, oracle, mysql, postgresql etc.).

https://docs.spring.io/spring-boot/docs/current/reference/html/howto-database-initialization.html

Kentkenta answered 7/10, 2009 at 12:25 Comment(0)
D
2

If you are using JPA you can usually configure your JPA provider so that it creates/updates the tables on initialization.

E.g. for hibernate, specify the property hibernate.hbm2ddl.auto and set its value to create-drop (should be fine for testing).

See also: Hibernate Documentation, Chapter 3 Configuration

However, make sure that the JPA provider is the first to access the DB ;)

Dashtikavir answered 7/10, 2009 at 12:25 Comment(0)
P
0

I just wanted to chime in and say that this was very helpful for me. I needed to connect to an Oracle database and export it to an XML file, then import it as a test HSQL database and access it with Hibernate. I used this code to create the tables before doing

DatabaseOperation.CLEAN_INSERT.execute(conn, dataset);. 

A word of caution though, this code sets the first column of each table as the primary key, so be careful if you use relationship tables as you may get a "Primary key constraint violation" on import. Thanks for the code snippet!

Patrickpatrilateral answered 7/10, 2009 at 12:25 Comment(1)
This does not create any tables, the code just inserts data from the provided dataset.Alathia

© 2022 - 2024 — McMap. All rights reserved.