简体   繁体   中英

How to exclude a column during INSERT with dbunit to HSQLDB

I export data from MS SQLServer to an xml file, then use that dataset in running unit tests that require database. I use dbunit maven plugin for it.

Unfortunately for me, not all columns in some tables are mapped in my Entity classes.

As an example, say, we have a table called 'member'. Member table has three columns: memberid, membername, memberrank. When I do an export, I get all three columns exported. But in my MemberEntity class, I only map memberid and membername, because I do not need memberrank in my application. So I would have the MemberEntity looking like this:

@Entity
@Table(name = "member")
public class MemberEntity {

    @Id
    @GeneratedValue()
    @Column(name = "memberid", nullable = false)
    private Integer memberid;
    @Column(name = "membername", nullable = false)
    private String membername;
...
}

Then, I try to insert dataset into HSQLDB before a test case:

IDatabaseConnection conn = new DatabaseConnection(((SessionImpl) (entityManager.getDelegate())).connection());
IDataSet dataset = new XmlDataSet(
resourceLoader.getResource("classpath:dataset.xml").getInputStream());
conn.getConfig().setProperty("http://www.dbunit.org/properties/datatypeFactory", new MsSqlDataTypeFactory());
DatabaseOperation.CLEAN_INSERT.execute(conn, dataset);

At this point, I get an exception saying the column MemberRank does not exist. It says something like the following:

org.dbunit.dataset.NoSuchColumnException: MEMBER.MEMBERRANK -  (Non-uppercase input column: memberrank) in ColumnNameToIndexes cache map. Note that the map's column names are NOT case sensitive.

When I remove the column from the dataset, all is well. If I add in the memberRank mapping to my Entity class, again, all goes well. But I cannot add the column mapping into my Entity class. Is there an easy way (other than removing the column and the associated data from the exported dataset manually) of excluding that column from being (attempted to be) added in when I do INSERT?

In hibernate every non static non transient property (field or method depending on the access type) of an entity is considered persistent, unless you annotate it as @Transient.

for example,

@Transient
public int counter; //transient property

private String firstname; //persistent property

The methods and fields annotated as @Transient will be ignored by the entity manager.See here for more information.

Maybe this answer comes a little bit late, but I've just run into a similar problem and wrote the following method to solve it (I'm using dbUnit 2.5.0). Hope it helps somebody.

/**
 * Generates a new data set with the columns declared in the
 * "excludedColumns" map removed.
 * 
 * @param src
 *            Source data set.
 * @param excludedColumns
 *            Map of table names and column names. Columns in this map are
 *            removed in the resulting data set.
 * @return Data set with the columns declared in the "excludedColumns" map
 *         removed. Tables that are not specified in the "excludedColumns"
 *         map are left untouched.
 * @throws DataSetException
 */
public static IDataSet filterDataSet(IDataSet src,
        Map<String, Set<String>> excludedColumns) throws DataSetException {
    if (excludedColumns == null) {
        return src;
    }

    ArrayList<ITable> tables = new ArrayList<ITable>(
            src.getTableNames().length);

    for (String tableName : src.getTableNames()) {

        if (excludedColumns.containsKey(tableName)) {
            ITable filteredTable = DefaultColumnFilter
                    .excludedColumnsTable(
                            src.getTable(tableName),
                            excludedColumns.get(tableName).toArray(
                                    new String[0]));

            tables.add(filteredTable);
        } else {
            tables.add(src.getTable(tableName));
        }
    }

    return new DefaultDataSet(tables.toArray(new ITable[0]),
            src.isCaseSensitiveTableNames());
}

The core of the method is DefaultColumnFilter . I'm using a commodity static method here, but an instance of DefaultColumnFilter gives a lot of flexibility.

I wonder if there is a more straight forward way of doing this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM