2012-02-03 5 views
6

Sto tentando di configurare l'ambiente di test dell'unità per utilizzare DbUnit.Utilizzo di DbUnit con tabelle che non dispongono di chiavi primarie

Ho qualche problema in quanto le tabelle che sto tentando di controllare non hanno le chiavi primarie. Ho ricevuto uno org.dbunit.dataset.NoPrimaryKeyException.

Ho seguito i passi qui http://dbunit.wikidot.com/noprimarykeytable ma Come si usa:

connection.getConfig().setProperty("http://www.dbunit.org/properties/primaryKeyFilter", new MyPrimaryKeyFilter("A1")); 

per ciascuno dei miei tavoli?

Per esempio, io ho il seguente database:

CREATE TABLE `NO_PK1` (
    `A1` int(11) NOT NULL, 
    `A2` varchar(50) default NULL 
); 

<?xml version="1.0" encoding="UTF-8"?> 
<dataset> 
    <NO_PK1 A1="1" A2="Test1" /> 
    <NO_PK1 A1="2" A2="Test2" /> 
    <NO_PK1 A1="3" /> 
</dataset> 

CREATE TABLE `NO_PK2` (
    `B1` int(11) NOT NULL, 
    `B2` varchar(50) default NULL 
); 

<?xml version="1.0" encoding="UTF-8"?> 
<dataset> 
    <NO_PK2 B1="1" B2="Test1" /> 
    <NO_PK2 B1="2" B2="Test2" /> 
    <NO_PK2 B1="3" /> 
</dataset> 

CREATE TABLE `NO_PK3` (
    `C1` int(11) NOT NULL, 
    `C2` varchar(50) default NULL 
); 

<?xml version="1.0" encoding="UTF-8"?> 
<dataset> 
    <NO_PK3 C1="1" C2="Test1" /> 
    <NO_PK3 C1="2" C2="Test2" /> 
    <NO_PK3 C1="3" /> 
</dataset> 

Come posso riscrivere connection.getConfig().setProperty("http://www.dbunit.org/properties/primaryKeyFilter", new MyPrimaryKeyFilter("A1")); in questo caso?

Molte grazie per qualsiasi consiglio.

risposta

5

È necessario assicurarsi che MyPrimaryKeyFilter gestisca tutte le tabelle nello schema. Nell'esempio, c'è solo una tabella, quindi la semplice classe di filtro fornita funziona bene. Nel tuo caso, probabilmente cambiare questa classe per prendere una mappa tabella contenente -> mappature nome della colonna PK:

class MyPrimaryKeyFilter implements IColumnFilter { 
     private Map<String, String> pseudoKey = null; 

     MyPrimaryKeyFilter(Map<String, String> pseudoKey) { 
      this.pseudoKey = pseudoKey; 
     } 

     public boolean accept(String tableName, Column column) { 
      return column.getColumnName().equalsIgnoreCase(pseudoKey.get(tableName)); 
     } 

    } 

e quindi impostare la mappa con {NO_PK1 -> A1}, {NO_PK2 -> B1} e {NO_PK3 -> C1} voci.

+0

Grazie slushi. Ciò ha senso. Che dire se uno dei tavoli ha una chiave composta da più di un campo? – mip

+1

Penso che ci sia possibile cambiare la Mappa in una mappa > e fare un controllo di contee. – slushi

+0

Quindi l'istruzione return diventa 'return pseudoKey.get (tableName) .contains (column.getColumnName());'? – mip

3

cado in stesso problema e la soluzione trovata in questi blog:

autori Tutti del blog Iniziamo dalla http://dbunit.wikidot.com/noprimarykeytable

Questo codice visualizzato diverso strategie per il controllo di id:

public static IDatabaseConnection getConnection(DataSource ds) throws Exception { 
    Connection con = ds.getConnection(); 
    final DatabaseMetaData dbMetaData = con.getMetaData(); 
    DatabaseConnection dbUnitCon = new DatabaseConnection(con, dbMetaData.getUserName().toUpperCase()); 
    DatabaseConfig dbUnitConfig = dbUnitCon.getConfig(); 
    dbUnitConfig.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new Oracle10DataTypeFactory()); 
    dbUnitConfig.setProperty(DatabaseConfig.FEATURE_SKIP_ORACLE_RECYCLEBIN_TABLES, Boolean.TRUE); 
    dbUnitConfig.setProperty(DatabaseConfig.PROPERTY_PRIMARY_KEY_FILTER, new IColumnFilter() { 

     Map<String, List<String>> tablePrimaryKeyMap = new HashMap<>(); 
     { 
      tablePrimaryKeyMap.put("CLIENT", Arrays.asList(new String[]{"FIRST_NAME", "MIDDLE_NAME", "LAST_NAME"})); 
      // ... 
     } 

     @Override 
     public boolean accept(String tableName, Column column) { 
      if ((tableName.startsWith("DATA_") || tableName.startsWith("PAYMENT_")) 
        && ("COMPANY".equalsIgnoreCase(tableName) || "FILIAL".equalsIgnoreCase(tableName) 
         || "BRANCH".equalsIgnoreCase(tableName) || "CASTOMER".equalsIgnoreCase(tableName) 
         || "XDATE".equalsIgnoreCase(tableName))) 
       return true; 
      if (tablePrimaryKeyMap.containsKey(tableName)) 
       return tablePrimaryKeyMap.get(tableName).contains(column.getColumnName()); 
      else if ("id".equalsIgnoreCase(column.getColumnName())) { 
       return true; 
      } 
      try { 
       ResultSet rs = dbMetaData.getPrimaryKeys(null, null, tableName); 
       while (rs.next()) { 
        rs.getString("COLUMN_NAME"); 
        if (rs.getString("COLUMN_NAME").equalsIgnoreCase(column.getColumnName())) { 
         return true; 
        } 
       } 
      } catch (SQLException ex) { 
       Logger.getLogger(DistributionControllerDbTest.class.getName()).log(Level.SEVERE, null, ex); 
      } 
      return false; 
     } 
    }); 
    return dbUnitCon; 
} 
Problemi correlati