in log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/JdbcDatabaseManager.java [799:884]
protected void writeInternal(final LogEvent event, final Serializable serializable) {
StringReader reader = null;
try {
if (!this.isRunning() || isClosed(this.connection) || isClosed(this.statement)) {
throw new AppenderLoggingException(
"Cannot write logging event; JDBC manager not connected to the database, running=%s, [%s]).",
isRunning(), fieldsToString());
}
// Clear in case there are leftovers.
statement.clearParameters();
if (serializable instanceof MapMessage) {
setFields((MapMessage<?, ?>) serializable);
}
int j = 1; // JDBC indices start at 1
if (this.factoryData.columnMappings != null) {
for (final ColumnMapping mapping : this.factoryData.columnMappings) {
if (ThreadContextMap.class.isAssignableFrom(mapping.getType())
|| ReadOnlyStringMap.class.isAssignableFrom(mapping.getType())) {
this.statement.setObject(j++, event.getContextData().toMap());
} else if (ThreadContextStack.class.isAssignableFrom(mapping.getType())) {
this.statement.setObject(j++, event.getContextStack().asList());
} else if (Date.class.isAssignableFrom(mapping.getType())) {
this.statement.setObject(j++, DateTypeConverter.fromMillis(event.getTimeMillis(),
mapping.getType().asSubclass(Date.class)));
} else {
final StringLayout layout = mapping.getLayout();
if (layout != null) {
if (Clob.class.isAssignableFrom(mapping.getType())) {
this.statement.setClob(j++, new StringReader(layout.toSerializable(event)));
} else if (NClob.class.isAssignableFrom(mapping.getType())) {
this.statement.setNClob(j++, new StringReader(layout.toSerializable(event)));
} else {
final Object value = TypeConverters.convert(layout.toSerializable(event),
mapping.getType(), null);
setStatementObject(j++, mapping.getNameKey(), value);
}
}
}
}
}
for (final ColumnConfig column : this.columnConfigs) {
if (column.isEventTimestamp()) {
this.statement.setTimestamp(j++, new Timestamp(event.getTimeMillis()));
} else if (column.isClob()) {
reader = new StringReader(column.getLayout().toSerializable(event));
if (column.isUnicode()) {
this.statement.setNClob(j++, reader);
} else {
this.statement.setClob(j++, reader);
}
} else if (column.isUnicode()) {
this.statement.setNString(j++, Objects.toString(
truncate(column.getColumnNameKey(), column.getLayout().toSerializable(event)), null));
} else {
this.statement.setString(j++, Objects.toString(
truncate(column.getColumnNameKey(), column.getLayout().toSerializable(event)), null));
}
}
if (isBuffered() && this.isBatchSupported) {
logger().debug("addBatch for {}", this.statement);
this.statement.addBatch();
} else {
final int executeUpdate = this.statement.executeUpdate();
logger().debug("executeUpdate = {} for {}", executeUpdate, this.statement);
if (executeUpdate == 0) {
throw new AppenderLoggingException(
"No records inserted in database table for log event in JDBC manager [%s].", fieldsToString());
}
}
} catch (final SQLException e) {
throw new DbAppenderLoggingException(e, "Failed to insert record for log event in JDBC manager: %s [%s]", e,
fieldsToString());
} finally {
// Release ASAP
try {
// statement can be null when a AppenderLoggingException is thrown at the start of this method
if (statement != null) {
statement.clearParameters();
}
} catch (final SQLException e) {
// Ignore
}
Closer.closeSilently(reader);
}
}