diff --git a/symmetric/symmetric-io/src/main/java/org/jumpmind/symmetric/io/data/writer/DefaultDatabaseWriterConflictResolver.java b/symmetric/symmetric-io/src/main/java/org/jumpmind/symmetric/io/data/writer/DefaultDatabaseWriterConflictResolver.java index 519a716285..4418dbf07f 100644 --- a/symmetric/symmetric-io/src/main/java/org/jumpmind/symmetric/io/data/writer/DefaultDatabaseWriterConflictResolver.java +++ b/symmetric/symmetric-io/src/main/java/org/jumpmind/symmetric/io/data/writer/DefaultDatabaseWriterConflictResolver.java @@ -3,6 +3,7 @@ import java.sql.Timestamp; import java.util.Map; +import org.apache.commons.lang.StringUtils; import org.jumpmind.db.model.Column; import org.jumpmind.db.model.Table; import org.jumpmind.db.sql.DmlStatement; @@ -11,6 +12,7 @@ import org.jumpmind.symmetric.io.data.DataEventType; import org.jumpmind.symmetric.io.data.writer.Conflict.DetectConflict; import org.jumpmind.symmetric.io.data.writer.DatabaseWriter.LoadStatus; +import org.jumpmind.util.Statistics; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -22,15 +24,37 @@ public void needsResolved(DatabaseWriter writer, CsvData data, LoadStatus loadSt DataEventType originalEventType = data.getDataEventType(); DatabaseWriterSettings writerSettings = writer.getWriterSettings(); Conflict conflict = writerSettings.pickConflict(writer.getTargetTable(), writer.getBatch()); - long statementCount = writer.getStatistics().get(writer.getBatch()) + Statistics statistics = writer.getStatistics().get(writer.getBatch()); + long statementCount = statistics .get(DataWriterStatisticConstants.STATEMENTCOUNT); + long lineNumber = statistics.get(DataWriterStatisticConstants.LINENUMBER); ResolvedData resolvedData = writerSettings.getResolvedData(statementCount); + + if (log.isDebugEnabled()) { + log.debug( + "Conflict detected: {} in batch {} at line {} for table {}", + new Object[] { conflict.getConflictId() == null ? "default" : conflict + .getConflictId(), writer.getBatch().getBatchId(), lineNumber, writer.getTargetTable().getFullyQualifiedTableName() }); + String csvData = data.getCsvData(CsvData.ROW_DATA); + if (StringUtils.isNotBlank(csvData)) { + log.debug("Row data: {}", csvData); + } + + csvData = data.getCsvData(CsvData.OLD_DATA); + if (StringUtils.isNotBlank(csvData)) { + log.debug("Old data: {}", csvData); + } + + csvData = resolvedData != null ? resolvedData.getResolvedData() : null; + if (StringUtils.isNotBlank(csvData)) { + log.debug("Resolve data: {}", csvData); + } + + } + switch (originalEventType) { case INSERT: switch (conflict.getResolveType()) { - case MANUAL: - attemptToResolve(resolvedData, data, writer, conflict); - break; case FALLBACK: performFallbackToUpdate(writer, data, conflict.isResolveChangesOnly()); break; @@ -51,22 +75,18 @@ public void needsResolved(DatabaseWriter writer, CsvData data, LoadStatus loadSt } break; case IGNORE: + ignore(writer, conflict); + break; + case MANUAL: default: - if (conflict.isResolveRowOnly()) { - writer.getStatistics().get(writer.getBatch()) - .increment(DataWriterStatisticConstants.IGNORECOUNT); - } else { - throw new IgnoreBatchException(); - } + attemptToResolve(resolvedData, data, writer, conflict); break; + } break; case UPDATE: switch (conflict.getResolveType()) { - case MANUAL: - attemptToResolve(resolvedData, data, writer, conflict); - break; case FALLBACK: performFallbackToInsert(writer, data); break; @@ -83,20 +103,25 @@ public void needsResolved(DatabaseWriter writer, CsvData data, LoadStatus loadSt } break; case IGNORE: + ignore(writer, conflict); + break; + case MANUAL: default: - if (conflict.isResolveRowOnly()) { - writer.getStatistics().get(writer.getBatch()) - .increment(DataWriterStatisticConstants.IGNORECOUNT); - } else { - throw new IgnoreBatchException(); - } + attemptToResolve(resolvedData, data, writer, conflict); break; + } break; case DELETE: switch (conflict.getResolveType()) { + case IGNORE: + writer.getStatistics().get(writer.getBatch()) + .increment(DataWriterStatisticConstants.MISSINGDELETECOUNT); + ignore(writer, conflict); + break; case MANUAL: + default: if (resolvedData != null) { if (!resolvedData.isIgnoreRow()) { writer.delete(data, false); @@ -106,17 +131,8 @@ public void needsResolved(DatabaseWriter writer, CsvData data, LoadStatus loadSt } } } - default: - case IGNORE: - if (conflict.isResolveRowOnly()) { - writer.getStatistics().get(writer.getBatch()) - .increment(DataWriterStatisticConstants.IGNORECOUNT); - writer.getStatistics().get(writer.getBatch()) - .increment(DataWriterStatisticConstants.MISSINGDELETECOUNT); - break; - } else { - throw new IgnoreBatchException(); - } + break; + } break; @@ -125,6 +141,15 @@ public void needsResolved(DatabaseWriter writer, CsvData data, LoadStatus loadSt } } + protected void ignore(DatabaseWriter writer, Conflict conflict) { + if (conflict.isResolveRowOnly()) { + writer.getStatistics().get(writer.getBatch()) + .increment(DataWriterStatisticConstants.IGNORECOUNT); + } else { + throw new IgnoreBatchException(); + } + } + protected void attemptToResolve(ResolvedData resolvedData, CsvData data, DatabaseWriter writer, Conflict conflict) { if (resolvedData != null) { diff --git a/symmetric/symmetric-io/src/test/java/org/jumpmind/symmetric/io/data/writer/DatabaseWriterTest.java b/symmetric/symmetric-io/src/test/java/org/jumpmind/symmetric/io/data/writer/DatabaseWriterTest.java index 1ab4116a02..bbdd335c7e 100644 --- a/symmetric/symmetric-io/src/test/java/org/jumpmind/symmetric/io/data/writer/DatabaseWriterTest.java +++ b/symmetric/symmetric-io/src/test/java/org/jumpmind/symmetric/io/data/writer/DatabaseWriterTest.java @@ -43,6 +43,7 @@ public void notExpectingError() { @Test public void testUpdateDetectTimestampNewerWins() { Conflict setting = new Conflict(); + setting.setConflictId("unit.test"); setting.setDetectType(DetectConflict.USE_TIMESTAMP); setting.setDetectExpression("time_value"); setting.setResolveRowOnly(true); @@ -76,6 +77,7 @@ public void testUpdateDetectTimestampNewerWins() { @Test public void testInsertDetectTimestampNewerWins() { Conflict setting = new Conflict(); + setting.setConflictId("unit.test"); setting.setDetectType(DetectConflict.USE_TIMESTAMP); setting.setDetectExpression("time_value"); setting.setResolveRowOnly(true); @@ -107,6 +109,7 @@ public void testInsertDetectTimestampNewerWins() { @Test public void testUpdateDetectVersionNewWins() { Conflict setting = new Conflict(); + setting.setConflictId("unit.test"); setting.setDetectType(DetectConflict.USE_VERSION); setting.setDetectExpression("integer_value"); setting.setResolveRowOnly(true); @@ -139,6 +142,7 @@ public void testUpdateDetectVersionNewWins() { @Test public void testUpdateDetectVersionIgnoreBatch() { Conflict setting = new Conflict(); + setting.setConflictId("unit.test"); setting.setDetectType(DetectConflict.USE_VERSION); setting.setDetectExpression("integer_value"); setting.setResolveRowOnly(false); diff --git a/symmetric/symmetric-util/src/test/resources/log4j.xml b/symmetric/symmetric-util/src/test/resources/log4j.xml index d2e2574c86..d5b58d725c 100644 --- a/symmetric/symmetric-util/src/test/resources/log4j.xml +++ b/symmetric/symmetric-util/src/test/resources/log4j.xml @@ -13,6 +13,10 @@ + + + +