2012-02-03 18 views
6

Próbuję skonfigurować moje środowisko testowe do używania DbUnit.Używanie DbUnit z tabelami, które nie mają kluczy podstawowych

Mam kilka problemów, ponieważ tabele, które próbuję kontrolować, nie mają kluczy podstawowych. Otrzymałem numer org.dbunit.dataset.NoPrimaryKeyException.

śledzę kroki tutaj http://dbunit.wikidot.com/noprimarykeytable ale jak mam użyć:

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

dla każdego z moich tabel?

Na przykład mam następujące bazy danych:

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> 

Jak mogę przepisać connection.getConfig().setProperty("http://www.dbunit.org/properties/primaryKeyFilter", new MyPrimaryKeyFilter("A1")); w tym przypadku?

Wielkie dzięki za radę.

Odpowiedz

5

Musisz się upewnić, że Twój filtr MyPrimaryKeyFilter obsługuje wszystkie tabele w twoim schemacie. W tym przykładzie jest tylko jedna tabela, więc prosta klasa filtra działa dobrze. W twoim przypadku, to pewnie zmieni tej klasy wziąć mapę zawierającą tabelę -> nazwa kolumny pk mapowania:

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

    } 

a następnie skonfigurować mapę z {NO_PK1 -> A1}, {NO_PK2 -> B1} i {NO_PK3 -> C1} wpisów.

+0

Dzięki slushi. To ma sens. A co jeśli jedna z tabel ma klucz złożony z więcej niż jednego pola? – mip

+1

Myślę, że możesz zmienić mapę na mapę > i wykonać test zawierający. – slushi

+0

Tak więc instrukcja return staje się 'return pseudoKey.get (tableName) .contains (column.getColumnName());'? – mip

3

wpadam samej kwestii i znalazł rozwiązanie w tych blogach:

autorów z bloga zacząć od http://dbunit.wikidot.com/noprimarykeytable

pokazano Ten kod różne strategie sprawdzania identyfikatora:

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; 
} 
Powiązane problemy