From 50788bb6cccfe4aacf0551f115bbaf22740d1c66 Mon Sep 17 00:00:00 2001 From: "Hicks, Josh" Date: Wed, 1 Feb 2017 10:25:07 -0500 Subject: [PATCH] 0002976: Foreign key automatic resolution was not handling nested dependencies properly --- .../symmetric/service/impl/DataService.java | 99 ++++++++++--------- 1 file changed, 54 insertions(+), 45 deletions(-) diff --git a/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/DataService.java b/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/DataService.java index 10f8933728..4c6f716fb2 100644 --- a/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/DataService.java +++ b/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/DataService.java @@ -1550,51 +1550,56 @@ public String reloadTable(String nodeId, String catalogName, String schemaName, } public void reloadMissingForeignKeyRows(String nodeId, long dataId) { - Data data = findData(dataId); - log.debug("reloadMissingForeignKeyRows for nodeId '{}' dataId '{}' table '{}'", nodeId, dataId, data.getTableName()); - TriggerHistory hist = data.getTriggerHistory(); - Table table = platform.getTableFromCache(hist.getSourceCatalogName(), hist.getSourceSchemaName(), hist.getSourceTableName(), false); - Map dataMap = data.toColumnNameValuePairs(table.getColumnNames(), CsvData.ROW_DATA); - - List tableRows = new ArrayList(); - Row row = new Row(dataMap.size()); - row.putAll(dataMap); - tableRows.add(new TableRow(table, row, null, null, null)); - List foreignTableRows; try { - foreignTableRows = getForeignTableRows(tableRows); - } catch (CloneNotSupportedException e) { - throw new RuntimeException(e); - } - - if (foreignTableRows.isEmpty()) { - log.info("Could not determine foreign table rows to fix foreign key violation for " - + "nodeId '{}' dataId '{}' table '{}'", nodeId, dataId, data.getTableName()); - } - - Collections.reverse(foreignTableRows); - Set visited = new HashSet(); - - for (TableRow foreignTableRow : foreignTableRows) { - if (visited.add(foreignTableRow)) { - Table foreignTable = foreignTableRow.getTable(); - String catalog = foreignTable.getCatalog(); - String schema = foreignTable.getSchema(); - if (StringUtils.equals(platform.getDefaultCatalog(), catalog)) { - catalog = null; - } - if (StringUtils.equals(platform.getDefaultSchema(), schema)) { - schema = null; - } + Data data = findData(dataId); + log.debug("reloadMissingForeignKeyRows for nodeId '{}' dataId '{}' table '{}'", nodeId, dataId, data.getTableName()); + TriggerHistory hist = data.getTriggerHistory(); + Table table = platform.getTableFromCache(hist.getSourceCatalogName(), hist.getSourceSchemaName(), hist.getSourceTableName(), false); + Map dataMap = data.toColumnNameValuePairs(table.getColumnNames(), CsvData.ROW_DATA); + + List tableRows = new ArrayList(); + Row row = new Row(dataMap.size()); + row.putAll(dataMap); + tableRows.add(new TableRow(table, row, null, null, null)); + List foreignTableRows; + try { + foreignTableRows = getForeignTableRows(tableRows); + } catch (CloneNotSupportedException e) { + throw new RuntimeException(e); + } - log.info("Issuing foreign key correction reload " - + "nodeId {} catalog '{}' schema '{}' foreign table name '{}' fk name '{}' where sql '{}' " - + "to correct dataId '{}' table '{}' for column '{}'", - nodeId, catalog, schema, foreignTable.getName(), foreignTableRow.getFkName(), foreignTableRow.getWhereSql(), - dataId, data.getTableName(), foreignTableRow.getReferenceColumnName()); - reloadTable(nodeId, catalog, schema, foreignTable.getName(), foreignTableRow.getWhereSql()); + if (foreignTableRows.isEmpty()) { + log.info("Could not determine foreign table rows to fix foreign key violation for " + + "nodeId '{}' dataId '{}' table '{}'", nodeId, dataId, data.getTableName()); } - } + + Collections.reverse(foreignTableRows); + Set visited = new HashSet(); + + for (TableRow foreignTableRow : foreignTableRows) { + if (visited.add(foreignTableRow)) { + Table foreignTable = foreignTableRow.getTable(); + String catalog = foreignTable.getCatalog(); + String schema = foreignTable.getSchema(); + if (StringUtils.equals(platform.getDefaultCatalog(), catalog)) { + catalog = null; + } + if (StringUtils.equals(platform.getDefaultSchema(), schema)) { + schema = null; + } + + log.info("Issuing foreign key correction reload " + + "nodeId {} catalog '{}' schema '{}' foreign table name '{}' fk name '{}' where sql '{}' " + + "to correct dataId '{}' table '{}' for column '{}'", + nodeId, catalog, schema, foreignTable.getName(), foreignTableRow.getFkName(), foreignTableRow.getWhereSql(), + dataId, data.getTableName(), foreignTableRow.getReferenceColumnName()); + reloadTable(nodeId, catalog, schema, foreignTable.getName(), foreignTableRow.getWhereSql()); + } + } + } + catch (Exception e) { + log.error("Unknown exception while processing foreign key.", e); + } } protected List getForeignTableRows(List tableRows) throws CloneNotSupportedException { @@ -1635,9 +1640,13 @@ protected List getForeignTableRows(List tableRows) throws Cl Row foreignRow = new Row(foreignTable.getColumnCount()); if (foreignTable.getForeignKeyCount() > 0) { DmlStatement selectSt = platform.createDmlStatement(DmlType.SELECT, foreignTable, null); - Map values = sqlTemplate.queryForMap(selectSt.getSql(), - whereRow.toArray(foreignTable.getPrimaryKeyColumnNames())); - foreignRow.putAll(values); + Object[] keys = whereRow.toArray(foreignTable.getPrimaryKeyColumnNames()); + Map values = sqlTemplate.queryForMap(selectSt.getSql(), keys); + if (values == null) { + log.warn("Unable to reload rows for missing foreign key data, parent data not found. Using sql='{}' with keys '{}'",selectSt.getSql(), keys); + } else { + foreignRow.putAll(values); + } } TableRow foreignTableRow = new TableRow(foreignTable, foreignRow, whereSql,referenceColumnName, fk.getName());