2016-06-23 7 views
7

I DBUnit für einen Integrationstest bin mit, und vor dem Test die Ausführung von Code ich in diesen Fehler renne:DBUnit PostgresqlDataTypeFactory nicht erkennt nicht Aufzählungsliste

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. 

die Spalte, die ignoriert wird, ist eine Liste der enums. In dem Datensatz es wie folgt geschrieben:

<?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> 

ich in der DBUnit FAQ und sah this issue, die besagt, dass ich die isEnumType() -Methode außer Kraft zu setzen haben meine Enum zu unterstützen Postgresql ist, also tat ich dies:

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

Aber ich bekomme immer noch den gleichen Fehler, und ich weiß nicht warum. Vielleicht übertreibe ich die Methode nicht gut? Vielleicht ist es nicht einmal die Ursache meines Problems? Wenn Sie einen anderen Code benötigen, fragen Sie einfach, danke!

+0

Enthält Ihr Datensatz 'badges' eine Spalte' TRACK_TYPES'? –

+0

Können Sie mir Ihren Quellcode schicken? Ich werde versuchen, mich darauf einzulassen. –

+0

@KevinWallis Ich habe gerade die Frage aktualisiert, damit Sie die Datensatzzeile sehen können. Ja, es enthält diese Spalte, aber es wird ignoriert, wie der Fehler angibt. – alfizqu

Antwort

1

Nun ... ich war nicht in der Lage dies genau zu lösen, aber geschafft, es zu lösen durch einen Workaround.

Dieser Fehler tritt aufgrund der Annotation @DatabaseSetup auf. Wenn ich diesen Prozess ohne Verwendung von es mache, löst es immer noch einen "Spalte nicht erkannt" -Fehler aus, da es Postgres-Arrays nicht erkennt (das war die Hauptursache, die ich habe), aber ich könnte es lösen, indem ich eine neue DataTypeFactory erstelle von dem Standard ein:

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

Versuchen Sie, die Enum mit seinem Wert

enum.values(); 

es ein Array bestehen bleiben, als Sie dieses Element speichern

+0

wo sollte ich die enum beharren? In der Methode setUpDatabaseConfig? – alfizqu

+0

Versuchen Sie, einen 'EntityManager' zu verwenden, der eine 'persist (obj)' Methoden hat – Irazza

1

Es gibt nur begrenzte Unterstützung für postgresql Aufzählungen, weil nur das Lesen und Schreiben von Strings ist seit DBUnit 2.4.6 unterstützt. Um dies zu tun, müssen Sie die Methode „isEnumType“ in der PostgresqlDataTypeFactory wie dies außer Kraft setzen:

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

ich nächsten Fehler hatte:

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 fordert meta für Tabelle und erhält eine Art VARCHAR für Aufzählungen von PostgreSQL. Aber PostgreSQL akzeptiert diesen Typ nicht zurück.

overrode I Methoden aus PostgresqlDataTypeFactory in nächster Weise:

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

Dies setzt Typen für ENUM als OTHER und Mutter Methode super.createDataType(sqlType, sqlTypeName) schafft DataType in der richtigen Art und Weise.

PostgreSQL Version: 9.6.5
DbUnit Version: 2.5.4

Weitere Informationen könnten auf discussion finden.