DBUnit PostgresqlDataTypeFactory 不识别枚举列表
DBUnit PostgresqlDataTypeFactory does not recognizes enum list
我正在使用 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'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());
}
但我仍然得到同样的错误,我不知道为什么。也许我没有很好地覆盖该方法?也许这甚至不是我的问题的原因?
如果您需要任何其他代码,请询问,谢谢!
尝试用它的值来持久化枚举
enum.values();
它return一个数组比你保存这个元素
好吧...我无法完全解决这个问题,但设法通过变通办法解决了。
此错误是由于@DatabaseSetup 注释引起的。如果我在不使用它的情况下执行此过程,它仍然会抛出 'column not recognized' 错误,因为它无法识别 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);
}
}
对 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;
}
};
我有下一个错误:
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
请求 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 上找到更多信息。
我正在使用 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'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());
}
但我仍然得到同样的错误,我不知道为什么。也许我没有很好地覆盖该方法?也许这甚至不是我的问题的原因? 如果您需要任何其他代码,请询问,谢谢!
尝试用它的值来持久化枚举
enum.values();
它return一个数组比你保存这个元素
好吧...我无法完全解决这个问题,但设法通过变通办法解决了。
此错误是由于@DatabaseSetup 注释引起的。如果我在不使用它的情况下执行此过程,它仍然会抛出 'column not recognized' 错误,因为它无法识别 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);
}
}
对 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;
}
};
我有下一个错误:
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
请求 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 上找到更多信息。