DBUnit PostgresqlDataTypeFactory无法识别枚举列表

时间:2016-06-23 11:03:49

标签: java postgresql enums integration-testing dbunit

我正在使用DBUnit进行集成测试,在执行测试代码之前我遇到了这个错误:

badges.track_types data type (2003, '_text') not recognized and will be ignored. See FAQ for more information.

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

被忽略的列是枚举列表。 在数据集中,它是这样写的:

<?xml version='1.0' encoding='UTF-8'?>
<dataset>
  // More info ...
  <badges name="30&apos;000" description="30k a day" image_name="30000.png" threshold_val="30000.00000000" has_many="true" id="45" track_types="{TRACK_GENERIC}" "/> 
</dataset> 

我查看了DBUnit FAQ并看到了this issue,它说我必须覆盖isEnumType()方法来支持我的枚举是Postgresql,所以我这样做了:

/**
 * Override method to set custom properties/features
 */
protected void setUpDatabaseConfig(DatabaseConfig config) {

    config.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new PostgresqlDataTypeFactory(){
        public boolean isEnumType(String sqlTypeName) {
            if(sqlTypeName.equalsIgnoreCase("track_types")){
                return true;
            }
            return false;
        }
    });
    config.setProperty(DatabaseConfig.PROPERTY_METADATA_HANDLER, new DefaultMetadataHandler());
}

但我仍然得到同样的错误,我不知道为什么。也许我没有超越这个方法?也许它甚至不是我的问题的原因? 如果您需要任何其他代码,请询问,谢谢!

4 个答案:

答案 0 :(得分:2)

尝试使用其值

来保持枚举
enum.values();

它返回一个数组而不是保存这个元素

答案 1 :(得分:1)

嗯......我无法完全解决这个问题,但设法通过解决方法解决了这个问题。

由于@DatabaseSetup注释而出现此错误。如果我在不使用它的情况下完成了这个过程,它仍会引发一个未被识别的列。错误,因为它不识别postgres数组(这是我的根本原因),但我可以通过创建一个从默认值扩展的新DataTypeFactory来解决它:

public class PsqlArrayDataTypeFactory extends DefaultDataTypeFactory {
        public DataType createDataType(int sqlType, String sqlTypeName) throws DataTypeException {
            if (sqlType == Types.ARRAY)
            {
                return DataType.VARCHAR;
            }

            return super.createDataType(sqlType, sqlTypeName);
        }
    }

答案 2 :(得分:1)

我有下一个错误:

Caused by: org.postgresql.util.PSQLException: ERROR: column "status" is of type topic_status but expression is of type character varying
  Hint: You will need to rewrite or cast the expression.

DbUnit请求meta for table并从PostgreSQL接收枚举类型VARCHAR。但是PostgreSQL不会接受这种类型。

我以下一种方式覆盖PostgresqlDataTypeFactory的方法:

config.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, 
    new PostgresqlDataTypeFactory() {
        @Override
        public boolean isEnumType(String sqlTypeName) {
            return "topic_status".equalsIgnoreCase(sqlTypeName);
        }

        @Override
        public DataType createDataType(int sqlType, String sqlTypeName) throws DataTypeException {
            if (isEnumType(sqlTypeName)) {
                sqlType = Types.OTHER;
            }
            return super.createDataType(sqlType, sqlTypeName);
        }
    });
);

这会将枚举的类型设置为OTHER,而父方法super.createDataType(sqlType, sqlTypeName)会以适当的方式创建DataType

PostgreSQL版本:9.6.5
DbUnit版本:2.5.4

可在discussion找到更多信息。

答案 3 :(得分:0)

对postgresql枚举的支持有限,因为自dbunit 2.4.6起只支持读写字符串。为此,您必须覆盖PostgresqlDataTypeFactory中的方法“isEnumType”,如下所示:

PostgresqlDataTypeFactory factory = new PostgresqlDataTypeFactory(){
  public boolean isEnumType(String sqlTypeName) {
    if(sqlTypeName.equalsIgnoreCase("abc_enum")){
      return true;
    }
    return false;
  }
};