【问题标题】:How to exclude a column during INSERT with dbunit to HSQLDB如何在将 dbunit 插入到 HSQLDB 期间排除列
【发布时间】:2012-02-06 12:06:15
【问题描述】:

我将数据从 MS SQLServer 导出到一个 xml 文件,然后在运行需要数据库的单元测试中使用该数据集。我使用 dbunit maven 插件。

不幸的是,并非某些表中的所有列都映射到我的实体类中。

例如,假设我们有一个名为“member”的表。 成员表有三列:memberid、membername、memberrank。 当我进行导出时,我会导出所有三列。 但是在我的 MemberEntity 类中,我只映射 memberid 和 membername,因为我的应用程序中不需要 memberrank。所以我会让 MemberEntity 看起来像这样:

@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;
...
}

然后,我尝试在测试用例之前将数据集插入 HSQLDB:

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

此时,我收到一个异常,指出列 MemberRank 不存在。它是这样说的:

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.

当我从数据集中删除列时,一切都很好。如果我将 memberRank 映射添加到我的 Entity 类,再次,一切顺利。 但我无法将列映射添加到我的实体类中。是否有一种简单的方法(除了手动从导出的数据集中删除列和相关数据)在我执行 INSERT 时排除(尝试)添加该列?

【问题讨论】:

  • 您的问题解决了吗?我看不到任何 cmets 或接受的答案。

标签: java hibernate unit-testing hsqldb dbunit


【解决方案1】:

也许这个答案来得有点晚,但我刚刚遇到了类似的问题,并编写了以下方法来解决它(我使用的是 dbUnit 2.5.0)。希望它可以帮助某人。

/**
 * 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());
}

方法的核心是DefaultColumnFilter。我在这里使用的是商品静态方法,但是DefaultColumnFilter 的实例提供了很大的灵活性。

我想知道是否有更直接的方法来做到这一点。

【讨论】:

    【解决方案2】:

    在休眠实体的每个非静态非瞬态属性(取决于访问类型的字段或方法)都被认为是持久的,除非您将其注释为@Transient。

    例如,

    @Transient
    public int counter; //transient property
    
    private String firstname; //persistent property
    

    注解为@Transient 的方法和字段将被实体管理器忽略。有关详细信息,请参阅here

    【讨论】:

    • 这不是我想要的。我正在寻找一种方法让 DBUnit 忽略某些列,而不修改我的实体类。不过,我最终还是在我的实体类中添加了这些列。
    猜你喜欢
    • 2012-11-14
    • 2015-06-09
    • 1970-01-01
    • 2020-07-12
    • 2011-02-21
    • 1970-01-01
    • 2013-05-08
    • 1970-01-01
    • 2013-06-20
    相关资源
    最近更新 更多