I'm using DBUnit for an integration test, and before executing the test code I'm running into this error:
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.
the column that is ignored is a list of enums. In the dataset it's written like this :
<?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>
I looked in the DBUnit FAQ and saw this issue , that says that I have to override the isEnumType() method to support my enum is Postgresql, so I did this:
/**
* 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());
}
But I still get the same error, and I don't know why. Maybe I'm not overriding well the method? Maybe it's not even the cause of my problem? If you need any other code just ask, thanks!
Try to persist the enum with its value
enum.values();
it return an array than you save this element
Well... I wasn't able to solve this exactly but managed to solve it by a workaround.
This error comes because of the @DatabaseSetup annotation. If I did this process without using it, it still throws a 'column not recognized' error, because it doesn't recognize postgres arrays (that was the root cause that I have) but I could solve it by creating a new DataTypeFactory that extends from the default one:
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);
}
}
I had next error:
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
requests meta for table and receives a type VARCHAR
for enums from PostgreSQL. But PostgreSQL won't accept this type back.
I overrode methods from PostgresqlDataTypeFactory
in next way:
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);
}
});
);
This sets type for enum as OTHER
and parent method super.createDataType(sqlType, sqlTypeName)
creates DataType
in proper way.
PostgreSQL version: 9.6.5
DbUnit version: 2.5.4
More information could be found on discussion.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With