From edcdb41adc3588cd9342ca179f942b2b81c851a8 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Fri, 27 Jul 2012 18:43:39 +0200 Subject: [PATCH] [#1544] Remove Attachable interface from QueryPart hierarchy --- .../java/org/jooq/impl/AbstractQuery.java | 3 -- .../org/jooq/impl/DefaultBindContext.java | 29 ++++++++++++++++--- .../java/org/jooq/impl/FieldTypeHelper.java | 9 +++++- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractQuery.java b/jOOQ/src/main/java/org/jooq/impl/AbstractQuery.java index 5f224ca249..478c9c413d 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractQuery.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractQuery.java @@ -123,9 +123,6 @@ abstract class AbstractQuery extends AbstractQueryPart implements Query { throw new DetachedException("Cannot execute query. No Connection configured"); } - // Ensure that all depending Attachables are attached - attach(configuration); - int result = 0; try { listener.renderStart(ctx); diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultBindContext.java b/jOOQ/src/main/java/org/jooq/impl/DefaultBindContext.java index 641550bfeb..db52a43213 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DefaultBindContext.java +++ b/jOOQ/src/main/java/org/jooq/impl/DefaultBindContext.java @@ -49,6 +49,7 @@ import java.sql.Clob; import java.sql.Date; import java.sql.PreparedStatement; import java.sql.SQLException; +import java.sql.SQLOutput; import java.sql.Time; import java.sql.Timestamp; import java.sql.Types; @@ -76,10 +77,22 @@ class DefaultBindContext extends AbstractBindContext { /** * Generated UID */ - private static final long serialVersionUID = -5457385919209241505L; - private static final JooqLogger log = JooqLogger.getLogger(DefaultBindContext.class); + private static final long serialVersionUID = -5457385919209241505L; + private static final JooqLogger log = JooqLogger.getLogger(DefaultBindContext.class); - private final PreparedStatement stmt; + /** + * The localConfiguration is used to communicate a Configuration to an + * {@link ArrayRecord}, in case that ArrayRecord is serialised to a + * {@link SQLOutput} object. + *

+ * This is probably the only solution to circumvent this bad JDBC design. + * See also http://stackoverflow + * .com/q/11439543/521799 + */ + static ThreadLocal localConfiguration = new ThreadLocal(); + + private final PreparedStatement stmt; DefaultBindContext(Configuration configuration, PreparedStatement stmt) { super(configuration); @@ -311,7 +324,15 @@ class DefaultBindContext extends AbstractBindContext { bindValue(primaryKey, primaryKey.getClass()); } else { - stmt.setObject(nextIndex(), value); + try { + // [#1544] Set the local configuration, in case an array needs + // to be serialised to SQLOutput + localConfiguration.set(this); + stmt.setObject(nextIndex(), value); + } + finally { + localConfiguration.remove(); + } } return this; diff --git a/jOOQ/src/main/java/org/jooq/impl/FieldTypeHelper.java b/jOOQ/src/main/java/org/jooq/impl/FieldTypeHelper.java index b7ca9bd0dd..9955293c28 100644 --- a/jOOQ/src/main/java/org/jooq/impl/FieldTypeHelper.java +++ b/jOOQ/src/main/java/org/jooq/impl/FieldTypeHelper.java @@ -39,6 +39,7 @@ package org.jooq.impl; import static org.jooq.SQLDialect.CUBRID; import static org.jooq.SQLDialect.POSTGRES; import static org.jooq.impl.Factory.getNewFactory; +import static org.jooq.impl.Util.getDriverConnection; import static org.jooq.tools.reflect.Reflect.on; import java.math.BigDecimal; @@ -47,6 +48,7 @@ import java.sql.Array; import java.sql.Blob; import java.sql.CallableStatement; import java.sql.Clob; +import java.sql.Connection; import java.sql.Date; import java.sql.ResultSet; import java.sql.SQLException; @@ -346,7 +348,12 @@ public final class FieldTypeHelper { stream.writeString(value.toString()); } else if (ArrayRecord.class.isAssignableFrom(type)) { - stream.writeArray(((ArrayRecord) value).createArray()); + + // [#1544] We can safely assume that localConfiguration has been + // set on DefaultBindContext, prior to serialising arrays to SQLOut + Connection connection = getDriverConnection(DefaultBindContext.localConfiguration.get()); + ArrayRecord arrayRecord = (ArrayRecord) value; + stream.writeArray(on(connection).call("createARRAY", arrayRecord.getName(), arrayRecord.get()).get()); } else if (EnumType.class.isAssignableFrom(type)) { stream.writeString(((EnumType) value).getLiteral());