2016-06-23 26 views
7

sto usando DBUnit per un test di integrazione, e prima di eseguire il codice di prova che sto funzionando in questo errore:DBUnit PostgresqlDataTypeFactory non riconosce elenco enum

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. 

la colonna che viene ignorato è una lista di enumerazioni. Nel set di dati è scritto così:

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

mi sono guardato allo DBUnit FAQ e vide this issue, che dice che devo eseguire l'override del metodo isEnumType() per sostenere la mia enum è PostgreSQL, così ho fatto questo:

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

Ma ho ancora lo stesso errore, e non so perché. Forse non sto scavalcando bene il metodo? Forse non è nemmeno la causa del mio problema? Se hai bisogno di un altro codice basta chiedere, grazie!

+0

Il vostro set di dati 'badges' contiene una colonna' TRACK_TYPES'? –

+0

Puoi inviarmi il tuo codice sorgente? Proverò a scavare dentro. –

+0

@KevinWallis Ho appena aggiornato la domanda in modo da poter vedere la riga del set di dati. Sì, contiene quella colonna, ma viene ignorata come indica l'errore. – alfizqu

risposta

1

Beh ... non ero in grado di risolvere questo esattamente, ma sono riuscito a risolverlo da una soluzione.

Questo errore deriva dall'annotazione @DatabaseSetup. Se ho fatto questo processo senza usarlo, getta ancora un errore 'column not detected', perché non riconosce gli array Postgres (questa è la causa principale che ho) ma potrei risolverlo creando un nuovo DataTypeFactory che si estende da quella predefinita:

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

Prova a persistere l'enum con il suo valore

enum.values(); 

è restituire una matrice di salvare questo elemento

+0

dove dovrei persistere l'enum? Nel metodo setUpDatabaseConfig? – alfizqu

+0

Prova ad usare un 'EntityManager' ha metodi 'persist (obj)' – Irazza

1

C'è un supporto limitato per le enumerazioni PostgreSQL, in quanto solo la lettura e la scrittura di stringhe è supportato dal DBUnit 2.4.6. Per fare ciò è necessario eseguire l'override del metodo "isEnumType" nel PostgresqlDataTypeFactory come questo:

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

avevo prossimo errore:

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 chiede meta per la tavola e riceve un tipo VARCHAR per enumerazioni da PostgreSQL. Ma PostgreSQL non accetterà questo tipo indietro.

ho overrode metodi da PostgresqlDataTypeFactory in modo successivo:

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

Imposta tipo per enum come OTHER e il metodo genitore super.createDataType(sqlType, sqlTypeName) crea DataType in modo corretto.

versione di PostgreSQL: versione 9.6.5
DBUnit: 2.5.4

Maggiori informazioni possono essere trovate sul discussion.