From 790237e3f987f2df46dcbd5a0e489ec04906dfcd Mon Sep 17 00:00:00 2001 From: chenson42 Date: Wed, 14 Aug 2013 12:27:10 +0000 Subject: [PATCH] 0001334: The issue with jConnect JDBC, SQL Anywhere and decimal value. Better error handling. Common super class --- .../db/platform/ase/AseJdbcSqlTemplate.java | 83 +------------ .../SqlAnywhereJdbcSqlTemplate.java | 76 +----------- .../sybase/SybaseJdbcSqlTemplate.java | 116 ++++++++++++++++++ 3 files changed, 124 insertions(+), 151 deletions(-) create mode 100644 symmetric-jdbc/src/main/java/org/jumpmind/db/platform/sybase/SybaseJdbcSqlTemplate.java diff --git a/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/ase/AseJdbcSqlTemplate.java b/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/ase/AseJdbcSqlTemplate.java index 65615eb388..b2ae0bc401 100644 --- a/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/ase/AseJdbcSqlTemplate.java +++ b/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/ase/AseJdbcSqlTemplate.java @@ -20,35 +20,21 @@ */ package org.jumpmind.db.platform.ase; -import java.lang.reflect.Method; -import java.math.BigDecimal; -import java.sql.PreparedStatement; -import java.sql.SQLException; - import javax.sql.DataSource; import org.jumpmind.db.platform.DatabaseInfo; -import org.jumpmind.db.sql.ISqlTemplate; +import org.jumpmind.db.platform.sybase.SybaseJdbcSqlTemplate; import org.jumpmind.db.sql.ISqlTransaction; -import org.jumpmind.db.sql.JdbcSqlTemplate; import org.jumpmind.db.sql.SqlTemplateSettings; import org.jumpmind.db.sql.SymmetricLobHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.jdbc.core.SqlTypeValue; import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; -public class AseJdbcSqlTemplate extends JdbcSqlTemplate implements ISqlTemplate { - - static final Logger log = LoggerFactory.getLogger(AseJdbcSqlTemplate.class); - - private NativeJdbcExtractor nativeJdbcExtractor; +public class AseJdbcSqlTemplate extends SybaseJdbcSqlTemplate { public AseJdbcSqlTemplate(DataSource dataSource, SqlTemplateSettings settings, - SymmetricLobHandler lobHandler, DatabaseInfo databaseInfo, NativeJdbcExtractor nativeJdbcExtractor) { - super(dataSource, settings, lobHandler, databaseInfo); - this.nativeJdbcExtractor = nativeJdbcExtractor; - primaryKeyViolationCodes = new int[] {423,511,515,530,547,2601,2615,2714}; + SymmetricLobHandler lobHandler, DatabaseInfo databaseInfo, + NativeJdbcExtractor nativeJdbcExtractor) { + super(dataSource, settings, lobHandler, databaseInfo, nativeJdbcExtractor); } @Override @@ -56,63 +42,4 @@ public ISqlTransaction startSqlTransaction() { return new AseJdbcSqlTransaction(this); } - @Override - protected boolean allowsNullForIdentityColumn() { - return false; - } - - protected void setDecimalValue(PreparedStatement ps, int i, Object arg, int argType) - throws SQLException { - PreparedStatement nativeStatement = getNativeStmt(ps); - if (nativeStatement != null - && "com.sybase.jdbc4.jdbc.SybPreparedStatement".equals(nativeStatement.getClass() - .getName())) { - Class clazz = nativeStatement.getClass(); - Class[] parameterTypes = new Class[] { int.class, BigDecimal.class, int.class, - int.class }; - Method method = null; - try { - method = clazz.getMethod("setBigDecimal", parameterTypes); - BigDecimal value = null; - if (arg instanceof BigDecimal) { - value = (BigDecimal)arg; - } else if (arg != null) { - value = new BigDecimal(arg.toString()); - } - Object[] params = new Object[] { new Integer(i), value, - new Integer(value.precision()), new Integer(value.scale()) }; - method.invoke(nativeStatement, params); - } catch (Exception e) { - log.warn("Had trouble calling the Sybase stmt.setBigDecimal(int,BigDecimal,int,int) method", e); - super.setDecimalValue(ps, i, arg, argType); - } - } else { - super.setDecimalValue(ps, i, arg, argType); - } - } - - private PreparedStatement getNativeStmt(PreparedStatement ps) { - PreparedStatement stmt = ps; - try { - stmt = nativeJdbcExtractor.getNativePreparedStatement(ps); - } catch (SQLException ex) { - log.debug("Could not find a native preparedstatement using {}", nativeJdbcExtractor - .getClass().getName()); - } - return stmt; - } - - @Override - public void setValues(PreparedStatement ps, Object[] args) - throws SQLException { - super.setValues(ps, args); - if (args != null && args.length > 0) { - int[] argTypes = new int[args.length]; - for (int i = 0; i < argTypes.length; i++) { - argTypes[i] = SqlTypeValue.TYPE_UNKNOWN; - } - setValues(ps, args, argTypes, getLobHandler().getDefaultHandler()); - } - } - } diff --git a/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/sqlanywhere/SqlAnywhereJdbcSqlTemplate.java b/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/sqlanywhere/SqlAnywhereJdbcSqlTemplate.java index 5fd6a41afe..195d895de1 100644 --- a/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/sqlanywhere/SqlAnywhereJdbcSqlTemplate.java +++ b/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/sqlanywhere/SqlAnywhereJdbcSqlTemplate.java @@ -20,89 +20,19 @@ */ package org.jumpmind.db.platform.sqlanywhere; -import java.lang.reflect.Method; -import java.math.BigDecimal; -import java.sql.PreparedStatement; -import java.sql.SQLException; - import javax.sql.DataSource; import org.jumpmind.db.platform.DatabaseInfo; -import org.jumpmind.db.sql.ISqlTemplate; -import org.jumpmind.db.sql.JdbcSqlTemplate; +import org.jumpmind.db.platform.sybase.SybaseJdbcSqlTemplate; import org.jumpmind.db.sql.SqlTemplateSettings; import org.jumpmind.db.sql.SymmetricLobHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.jdbc.core.SqlTypeValue; import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; -public class SqlAnywhereJdbcSqlTemplate extends JdbcSqlTemplate implements ISqlTemplate { - - static final Logger log = LoggerFactory.getLogger(SqlAnywhereJdbcSqlTemplate.class); - - private NativeJdbcExtractor nativeJdbcExtractor; +public class SqlAnywhereJdbcSqlTemplate extends SybaseJdbcSqlTemplate { public SqlAnywhereJdbcSqlTemplate(DataSource dataSource, SqlTemplateSettings settings, SymmetricLobHandler lobHandler, DatabaseInfo databaseInfo, NativeJdbcExtractor nativeJdbcExtractor) { - super(dataSource, settings, lobHandler, databaseInfo); - this.nativeJdbcExtractor = nativeJdbcExtractor; - primaryKeyViolationCodes = new int[] {423,511,515,530,547,2601,2615,2714}; - } - - @Override - protected boolean allowsNullForIdentityColumn() { - return false; - } - - protected void setDecimalValue(PreparedStatement ps, int i, Object arg, int argType) - throws SQLException { - PreparedStatement nativeStatement = getNativeStmt(ps); - if (nativeStatement != null - && "com.sybase.jdbc4.jdbc.SybPreparedStatement".equals(nativeStatement.getClass() - .getName())) { - Class clazz = nativeStatement.getClass(); - Class[] parameterTypes = new Class[] { int.class, BigDecimal.class, int.class, - int.class }; - Method method = null; - - try { - method = clazz.getMethod("setBigDecimal", parameterTypes); - BigDecimal value = (BigDecimal) arg; - Object[] params = new Object[] { new Integer(i), value, - new Integer(value.precision()), - new Integer(value.scale()) }; - method.invoke(nativeStatement, params); - } catch (Exception e) { - log.info("Can't find stmt.setBigDecimal(int,BigDecimal,int,int) method: " - + e.getMessage()); - return; - } - } - } - - private PreparedStatement getNativeStmt(PreparedStatement ps) { - PreparedStatement stmt = ps; - try { - stmt = nativeJdbcExtractor.getNativePreparedStatement(ps); - } catch (SQLException ex) { - log.debug("Could not find a native preparedstatement using {}", nativeJdbcExtractor - .getClass().getName()); - } - return stmt; - } - - @Override - public void setValues(PreparedStatement ps, Object[] args) - throws SQLException { - super.setValues(ps, args); - if (args != null && args.length > 0) { - int[] argTypes = new int[args.length]; - for (int i = 0; i < argTypes.length; i++) { - argTypes[i] = SqlTypeValue.TYPE_UNKNOWN; - } - setValues(ps, args, argTypes, getLobHandler().getDefaultHandler()); - } + super(dataSource, settings, lobHandler, databaseInfo, nativeJdbcExtractor); } } diff --git a/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/sybase/SybaseJdbcSqlTemplate.java b/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/sybase/SybaseJdbcSqlTemplate.java new file mode 100644 index 0000000000..54b0081836 --- /dev/null +++ b/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/sybase/SybaseJdbcSqlTemplate.java @@ -0,0 +1,116 @@ +/** + * Licensed to JumpMind Inc under one or more contributor + * license agreements. See the NOTICE file distributed + * with this work for additional information regarding + * copyright ownership. JumpMind Inc licenses this file + * to you under the GNU General Public License, version 3.0 (GPLv3) + * (the "License"); you may not use this file except in compliance + * with the License. + * + * You should have received a copy of the GNU General Public License, + * version 3.0 (GPLv3) along with this library; if not, see + * . + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jumpmind.db.platform.sybase; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.math.BigDecimal; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.Arrays; + +import javax.sql.DataSource; + +import org.jumpmind.db.platform.DatabaseInfo; +import org.jumpmind.db.sql.ISqlTemplate; +import org.jumpmind.db.sql.JdbcSqlTemplate; +import org.jumpmind.db.sql.SqlTemplateSettings; +import org.jumpmind.db.sql.SymmetricLobHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.jdbc.core.SqlTypeValue; +import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; + +public class SybaseJdbcSqlTemplate extends JdbcSqlTemplate implements ISqlTemplate { + + static final Logger log = LoggerFactory.getLogger(SybaseJdbcSqlTemplate.class); + + private NativeJdbcExtractor nativeJdbcExtractor; + + public SybaseJdbcSqlTemplate(DataSource dataSource, SqlTemplateSettings settings, + SymmetricLobHandler lobHandler, DatabaseInfo databaseInfo, NativeJdbcExtractor nativeJdbcExtractor) { + super(dataSource, settings, lobHandler, databaseInfo); + this.nativeJdbcExtractor = nativeJdbcExtractor; + primaryKeyViolationCodes = new int[] {423,511,515,530,547,2601,2615,2714}; + } + + @Override + protected boolean allowsNullForIdentityColumn() { + return false; + } + + protected void setDecimalValue(PreparedStatement ps, int i, Object arg, int argType) + throws SQLException { + PreparedStatement nativeStatement = getNativeStmt(ps); + if (nativeStatement != null + && "com.sybase.jdbc4.jdbc.SybPreparedStatement".equals(nativeStatement.getClass() + .getName())) { + Class clazz = nativeStatement.getClass(); + Class[] parameterTypes = new Class[] { int.class, BigDecimal.class, int.class, + int.class }; + BigDecimal value = null; + if (arg instanceof BigDecimal) { + value = (BigDecimal)arg; + } else if (arg != null) { + value = new BigDecimal(arg.toString()); + } + Object[] params = new Object[] { new Integer(i), value, + new Integer(value.precision()), new Integer(value.scale()) }; + try { + Method method = clazz.getMethod("setBigDecimal", parameterTypes); + method.invoke(nativeStatement, params); + } catch (Throwable e) { + if (e instanceof InvocationTargetException) { + e = ((InvocationTargetException)e).getTargetException(); + } + log.warn(String.format("Error calling the Sybase stmt.setBigDecimal(%s) method", Arrays.toString(params)), e); + super.setDecimalValue(ps, i, arg, argType); + } + } else { + super.setDecimalValue(ps, i, arg, argType); + } + } + + private PreparedStatement getNativeStmt(PreparedStatement ps) { + PreparedStatement stmt = ps; + try { + stmt = nativeJdbcExtractor.getNativePreparedStatement(ps); + } catch (SQLException ex) { + log.debug("Could not find a native preparedstatement using {}", nativeJdbcExtractor + .getClass().getName()); + } + return stmt; + } + + @Override + public void setValues(PreparedStatement ps, Object[] args) + throws SQLException { + super.setValues(ps, args); + if (args != null && args.length > 0) { + int[] argTypes = new int[args.length]; + for (int i = 0; i < argTypes.length; i++) { + argTypes[i] = SqlTypeValue.TYPE_UNKNOWN; + } + setValues(ps, args, argTypes, getLobHandler().getDefaultHandler()); + } + } + +}