Example usage for java.sql PreparedStatement setObject

List of usage examples for java.sql PreparedStatement setObject

Introduction

In this page you can find the example usage for java.sql PreparedStatement setObject.

Prototype

void setObject(int parameterIndex, Object x) throws SQLException;

Source Link

Document

Sets the value of the designated parameter using the given object.

Usage

From source file:org.apache.torque.util.BasePeerImpl.java

/**
 * Executes an update against the database. The rows to be updated
 * are selected using <code>criteria</code> and updated using the values
 * in <code>updateValues</code>.
 *
 * @param criteria selects which rows of which table should be updated.
 * @param updateValues Which columns to update with which values, not null.
 * @param connection the database connection to use, not null.
 *
 * @return the number of affected rows./*from   ww w .  j  ava2 s  . co m*/
 *
 * @throws TorqueException if updating fails.
 */
public int doUpdate(org.apache.torque.criteria.Criteria criteria, ColumnValues updateValues,
        Connection connection) throws TorqueException {
    Query query = SqlBuilder.buildQuery(criteria);
    query.setType(Query.Type.UPDATE);

    query.getFromClause().clear();
    String fullTableName = SqlBuilder.getFullTableName(getTableMap().getFullyQualifiedTableName(),
            criteria.getDbName());
    query.getFromClause().add(new FromElement(fullTableName));

    List<JdbcTypedValue> replacementObjects = new ArrayList<JdbcTypedValue>();
    for (Map.Entry<Column, JdbcTypedValue> updateValue : updateValues.entrySet()) {
        Column column = updateValue.getKey();
        query.getSelectClause().add(column.getColumnName());
        replacementObjects.add(updateValue.getValue());
    }

    PreparedStatement preparedStatement = null;
    try {
        preparedStatement = connection.prepareStatement(query.toString());
        int position = 1;
        for (JdbcTypedValue replacementObject : replacementObjects) {
            Object value = replacementObject.getValue();
            if (value != null) {
                preparedStatement.setObject(position, value);
            } else {
                preparedStatement.setNull(position, replacementObject.getJdbcType());
            }
            position++;
        }
        List<Object> replacements = setPreparedStatementReplacements(preparedStatement,
                query.getPreparedStatementReplacements(), position - 1);
        long startTime = System.currentTimeMillis();
        log.debug("Executing update " + query.toString() + " using update parameters " + replacementObjects
                + " and query parameters " + replacements);

        int affectedRows = preparedStatement.executeUpdate();
        long queryEndTime = System.currentTimeMillis();
        log.trace("update took " + (queryEndTime - startTime) + " milliseconds");

        preparedStatement.close();
        preparedStatement = null;
        return affectedRows;
    } catch (SQLException e) {
        throw ExceptionMapper.getInstance().toTorqueException(e);
    } finally {
        if (preparedStatement != null) {
            try {
                preparedStatement.close();
            } catch (SQLException e) {
                log.warn("error closing prepared statement", e);
            }
        }
    }
}

From source file:org.apache.torque.util.BasePeerImpl.java

/**
 * Executes an update against the database. The rows to be updated
 * are selected using <code>criteria</code> and updated using the values
 * in <code>updateValues</code>.
 *
 * @param criteria selects which rows of which table should be updated.
 * @param updateValues Which columns to update with which values, not null.
 * @param connection the database connection to use, not null.
 *
 * @return the number of affected rows./*from w  w w  .  j  a va 2  s  . c  o  m*/
 *
 * @throws TorqueException if updating fails.
 *
 * @deprecated Please use doUpdate(org.apache.torque.criteria.Criteria,
 *                 ColumnValues, Connection).
 *             This method will be removed in a future version of Torque.
 */
@Deprecated
public int doUpdate(Criteria criteria, ColumnValues updateValues, Connection connection)
        throws TorqueException {
    Query query = SqlBuilder.buildQuery(criteria);
    query.setType(Query.Type.UPDATE);

    query.getFromClause().clear();
    String fullTableName = SqlBuilder.getFullTableName(getTableMap().getFullyQualifiedTableName(),
            criteria.getDbName());
    query.getFromClause().add(new FromElement(fullTableName));

    List<JdbcTypedValue> replacementObjects = new ArrayList<JdbcTypedValue>();
    for (Map.Entry<Column, JdbcTypedValue> updateValue : updateValues.entrySet()) {
        Column column = updateValue.getKey();
        query.getSelectClause().add(column.getColumnName());
        replacementObjects.add(updateValue.getValue());
    }

    PreparedStatement preparedStatement = null;
    try {
        preparedStatement = connection.prepareStatement(query.toString());
        int position = 1;
        for (JdbcTypedValue replacementObject : replacementObjects) {
            Object value = replacementObject.getValue();
            if (value != null) {
                preparedStatement.setObject(position, value);
            } else {
                preparedStatement.setNull(position, replacementObject.getJdbcType());
            }
            position++;
        }
        List<Object> replacements = setPreparedStatementReplacements(preparedStatement,
                query.getPreparedStatementReplacements(), position - 1);
        long startTime = System.currentTimeMillis();
        log.debug("Executing update " + query.toString() + " using update parameters " + replacementObjects
                + " and query parameters " + replacements);

        int affectedRows = preparedStatement.executeUpdate();
        long queryEndTime = System.currentTimeMillis();
        log.trace("update took " + (queryEndTime - startTime) + " milliseconds");

        preparedStatement.close();
        preparedStatement = null;
        return affectedRows;
    } catch (SQLException e) {
        throw ExceptionMapper.getInstance().toTorqueException(e);
    } finally {
        if (preparedStatement != null) {
            try {
                preparedStatement.close();
            } catch (SQLException e) {
                log.warn("error closing prepared statement", e);
            }
        }
    }
}

From source file:org.batoo.jpa.core.impl.criteria.QueryImpl.java

/**
 * Fills the statement with the parameters supplied.
 * //from w  w w. j ava 2 s  . com
 * @param statement
 *            the statement
 * @param parameters
 *            the parameters
 * @param repeat
 *            the parameter repeat map
 * @throws SQLException
 *             thrown in case of an underlying SQL Exception
 * 
 * @since 2.0.0
 */
private void fillStatement(PreparedStatement statement, Object[] parameters, Map<Integer, Integer> repeat)
        throws SQLException {
    // the following code has been adopted from Apache Commons DBUtils.

    // no paramaters nothing to do
    if ((parameters == null) || (parameters.length == 0)) {
        return;
    }

    final ParameterMetaData pmd = this.pmdBroken ? null : statement.getParameterMetaData();

    if (this.pmdBroken) {
        int total = parameters.length - repeat.size();

        if (repeat.size() > 0) {
            for (final Integer repeatSize : repeat.values()) {
                if (repeatSize != null) {
                    total += repeatSize;
                }
            }
        }

        ((PreparedStatementProxy) statement).setParamCount(total);
    }

    int index = 1;
    for (int i = 0; i < parameters.length; i++) {
        if (parameters[i] != null) {
            if (repeat.containsKey(i)) {
                final Object paramValue = parameters[i];

                if (paramValue instanceof Collection) {
                    final Collection<?> collection = (Collection<?>) paramValue;
                    for (final Object subParamValue : collection) {
                        statement.setObject(index++, subParamValue);
                    }
                } else {
                    final Object[] array = (Object[]) paramValue;
                    for (final Object subParamValue : array) {
                        statement.setObject(index++, subParamValue);
                    }
                }
            } else {
                statement.setObject(index++, parameters[i]);
            }
        } else {
            // VARCHAR works with many drivers regardless
            // of the actual column type. Oddly, NULL and
            // OTHER don't work with Oracle's drivers.
            int sqlType = Types.VARCHAR;
            if (!this.pmdBroken) {
                try {
                    sqlType = pmd.getParameterType(index + 1);
                } catch (final SQLException e) {
                    this.pmdBroken = true;
                }
            }

            statement.setNull(index++, sqlType);
        }
    }
}

From source file:org.nuxeo.ecm.core.storage.sql.Mapper.java

/**
 * Gets an array for a {@link CollectionFragment} from the database, given
 * its table name and id. If now rows are found, an empty array is returned.
 *
 * @param id the id/*from w  ww  .ja v  a 2 s .  co m*/
 * @param context the persistence context to which the read collection is
 *            tied
 * @return the array
 */
public Serializable[] readCollectionArray(Serializable id, Context context) throws StorageException {
    String tableName = context.getTableName();
    String sql = sqlInfo.selectFragmentById.get(tableName).sql;
    try {
        // XXX statement should be already prepared
        if (isLogEnabled()) {
            logSQL(sql, Collections.singletonList(id));
        }
        PreparedStatement ps = connection.prepareStatement(sql);
        try {
            List<Column> columns = sqlInfo.selectFragmentById.get(tableName).whatColumns;
            ps.setObject(1, id); // assumes only one primary column
            ResultSet rs = ps.executeQuery();

            // construct the resulting collection using each row
            Serializable[] array = model.newCollectionArray(rs, columns, context);
            if (isLogEnabled()) {
                log("  -> " + Arrays.asList(array));
            }
            return array;
        } finally {
            closePreparedStatement(ps);
        }
    } catch (SQLException e) {
        checkConnectionReset(e);
        throw new StorageException("Could not select: " + sql, e);
    }
}

From source file:org.nuxeo.ecm.core.storage.sql.Mapper.java

/**
 * Gets a per-id map of arrays for {@link CollectionFragment}s from the
 * database, given a table name and the ids.
 *
 * @param ids the ids/*from w ww  .j  ava 2  s  .  c  om*/
 * @param context the persistence context to which the read collection is
 *            tied
 * @return the map of id to array
 */
public Map<Serializable, Serializable[]> readCollectionsArrays(List<Serializable> ids, Context context)
        throws StorageException {
    if (ids.isEmpty()) {
        return Collections.emptyMap();
    }
    String tableName = context.getTableName();
    String[] orderBys = new String[] { model.MAIN_KEY, model.COLL_TABLE_POS_KEY }; // clusters results
    Set<String> skipColumns = new HashSet<String>(Arrays.asList(model.COLL_TABLE_POS_KEY));
    SQLInfoSelect select = sqlInfo.getSelectFragmentsByIds(tableName, ids.size(), orderBys, skipColumns);

    String sql = select.sql;
    try {
        if (isLogEnabled()) {
            logSQL(sql, ids);
        }
        PreparedStatement ps = connection.prepareStatement(sql);
        try {
            int i = 1;
            for (Serializable id : ids) {
                ps.setObject(i++, id);
            }
            ResultSet rs = ps.executeQuery();

            Map<Serializable, Serializable[]> res = model.newCollectionArrays(rs, select.whatColumns, context);
            // fill empty ones
            for (Serializable id : ids) {
                if (!res.containsKey(id)) {
                    Serializable[] array = model.getCollectionFragmentType(tableName).getEmptyArray();
                    res.put(id, array);
                }
            }
            if (isLogEnabled()) {
                for (Entry<Serializable, Serializable[]> entry : res.entrySet()) {
                    log("  -> " + entry.getKey() + " = " + Arrays.asList(entry.getValue()));
                }
            }
            return res;
        } finally {
            closePreparedStatement(ps);
        }
    } catch (SQLException e) {
        checkConnectionReset(e);
        throw new StorageException("Could not select: " + sql, e);
    }
}

From source file:org.apache.ctakes.jdl.data.loader.CsvLoader.java

/**
 * @param jdlConnection//from   w w w .  j  a  va 2  s .  c  om
 *            the jdlConnection to manage
 */
@Override
public final void dataInsert(final JdlConnection jdlConnection) {
    String sql = getSqlInsert(loader);
    if (log.isInfoEnabled())
        log.info(sql);
    Number ncommit = loader.getCommit();
    int rs = (loader.getSkip() == null) ? 0 : loader.getSkip().intValue();
    PreparedStatement preparedStatement = null;
    try {
        jdlConnection.setAutoCommit(false);
        // String[][] values = parser.getAllValues();
        preparedStatement = jdlConnection.getOpenConnection().prepareStatement(sql);
        boolean leftoversToCommit = false;
        // for (int r = rs; r < values.length; r++) {
        String[] row = null;
        int r = 0;
        do {
            row = parser.getLine();
            if (row == null)
                break;
            if (r < rs) {
                r++;
                continue;
            }
            r++;
            try {
                int cs = 0; // columns to skip
                int ce = 0; // columns from external
                int c = 0;
                // PreparedStatement preparedStatement = jdlConnection
                // .getOpenConnection().prepareStatement(sql);
                // if (ncommit == null) {
                // jdlConnection.setAutoCommit(true);
                // } else {
                // jdlConnection.setAutoCommit(false);
                // }
                for (Column column : loader.getColumn()) {
                    if (BooleanUtils.isTrue(column.isSkip())) {
                        cs++;
                    } else {
                        c++;
                        Object value = column.getConstant();
                        ce++;
                        if (value == null) {
                            if (column.getSeq() != null) {
                                value = r + column.getSeq().intValue();
                            } else {
                                // value = values[r][c + cs - ce];
                                value = row[c + cs - ce];
                                ce--;
                            }
                        }
                        if (value == null || (value instanceof String && ((String) value).length() == 0))
                            preparedStatement.setObject(c, null);
                        else {
                            // if there is a formatter, parse the string
                            if (this.formatMap.containsKey(column.getName())) {
                                try {
                                    preparedStatement.setObject(c,
                                            this.formatMap.get(column.getName()).parseObject((String) value));
                                } catch (Exception e) {
                                    System.err.println("Could not format '" + value + "' for column "
                                            + column.getName() + " on line " + r);
                                    e.printStackTrace(System.err);
                                    throw new RuntimeException(e);
                                }
                            } else {
                                preparedStatement.setObject(c, value);
                            }
                        }
                    }
                }
                preparedStatement.addBatch();
                leftoversToCommit = true;
                // preparedStatement.executeBatch();
                // executeBatch(preparedStatement);
                // if (!jdlConnection.isAutoCommit()
                // && (r % ncommit.intValue() == 0)) {
                if (r % ncommit.intValue() == 0) {
                    preparedStatement.executeBatch();
                    jdlConnection.commitConnection();
                    leftoversToCommit = false;
                    log.info("inserted " + ncommit.intValue() + " rows");
                }
            } catch (SQLException e) {
                // e.printStackTrace();
                throw new RuntimeException(e);
            }
        } while (row != null);
        if (leftoversToCommit) {
            preparedStatement.executeBatch();
            jdlConnection.commitConnection();
            leftoversToCommit = false;
        }
        log.info("inserted " + (r - rs) + " rows total");
    } catch (InstantiationException e) {
        log.error("", e);
    } catch (IllegalAccessException e) {
        log.error("", e);
    } catch (ClassNotFoundException e) {
        log.error("", e);
    } catch (IOException e) {
        log.error("", e);
    } catch (SQLException e) {
        throw new RuntimeException(e);
    } finally {
        if (preparedStatement != null) {
            try {
                preparedStatement.close();
            } catch (Exception e) {
            }
        }
    }
    // try {
    // if (!jdlConnection.isAutoCommit()) {
    // jdlConnection.commitConnection();
    // }
    // jdlConnection.closeConnection();
    // } catch (SQLException e) {
    // // TODO Auto-generated catch block
    // e.printStackTrace();
    // }
}

From source file:org.siphon.jssql.SqlExecutor.java

void setArg(PreparedStatement ps, int index, Object arg) throws SQLException, SqlExecutorException,
        UnsupportedDataTypeException, NoSuchMethodException, ScriptException {
    boolean output = false;
    int outputParameterType = 0;
    CallableStatement cs = null;/*from   w  ww .  j a  v  a 2  s.  c om*/
    if (ps instanceof CallableStatement) {
        cs = (CallableStatement) ps;
        if (arg instanceof ScriptObjectMirror && ((ScriptObjectMirror) arg).containsKey("OUT")) {
            ScriptObjectMirror jsarg = ((ScriptObjectMirror) arg);
            outputParameterType = (int) jsarg.get("JDBC_TYPE");
            arg = jsarg.get("VALUE");
            output = true;
        }
    }
    if (output) {
        cs.registerOutParameter(index + 1, outputParameterType);
        if (JsTypeUtil.isNull(arg) || (arg instanceof Double && Double.isNaN((Double) arg))) {
            return;
        }
    }

    if (JsTypeUtil.isNull(arg)) {
        ps.setObject(index + 1, null);
    } else if (arg instanceof CharSequence) {
        ps.setString(index + 1, arg.toString());
    } else if (arg instanceof NativeString) {
        ps.setString(index + 1, arg.toString());
    } else if (arg instanceof Double) { // js number always be
        // Doublebut if its came from
        // JSON.parse since JSON is jdk
        // given global object, it will
        // make Integer and ...
        double d = ((Double) arg).doubleValue();
        if (d == (int) d) {
            ps.setInt(index + 1, (int) d);
        } else if (d == (long) d) {
            ps.setLong(index + 1, (long) d);
        } else {
            ps.setBigDecimal(index + 1, new BigDecimal(d));
        }
    } else if (arg instanceof Integer) {
        ps.setInt(index + 1, (Integer) arg);
    } else if (arg instanceof Long) {
        ps.setLong(index + 1, (Long) arg);
    } else if (arg instanceof Float) {
        ps.setFloat(index + 1, (Float) arg);
    } else if (jsTypeUtil.isNativeDate(arg)) {
        ps.setTimestamp(index + 1, parseDate(arg));
    } else if (arg instanceof ZonedDateTime) {
        ZonedDateTime zdt = (ZonedDateTime) arg;
        ps.setTimestamp(index + 1, new Timestamp(zdt.toInstant().toEpochMilli()));
    } else if (arg instanceof Boolean) {
        ps.setBoolean(index + 1, JsTypeUtil.isTrue(arg));
    } else if (arg instanceof ScriptObjectMirror || arg instanceof ScriptObject) {
        String attr = null;
        Object value = null;
        if (arg instanceof ScriptObjectMirror) {
            ScriptObjectMirror atm = (ScriptObjectMirror) arg;
            if (atm.keySet().contains("toJavaObject")) {
                Object obj = atm.callMember("toJavaObject");
                setArg(ps, index, obj);
                return;
            }

            attr = atm.keySet().iterator().next();
            value = atm.get(attr);
        } else {
            ScriptObject obj = (ScriptObject) arg;
            if (obj.containsKey("toJavaObject")) {
                ScriptObjectMirror atm = (ScriptObjectMirror) jsTypeUtil.toScriptObjectMirror(obj);
                Object result = atm.callMember("toJavaObject");
                setArg(ps, index, result);
                return;
            }
            String[] arr = obj.getOwnKeys(false);
            if (arr.length == 0) {
                throw new SqlExecutorException("js argument " + arg + " (" + arg.getClass() + ") at " + index
                        + " is an empty js object");
            }
            attr = arr[0];
            value = obj.get(attr);
        }

        if ("STRING".equals(attr)) {
            ps.setString(index + 1, String.valueOf(value));
        } else if ("DECIMAL".equals(attr)) {
            if (value instanceof Double) {
                ps.setBigDecimal(index + 1, new BigDecimal((Double) value));
            } else {
                ps.setBigDecimal(index + 1, new BigDecimal(value + ""));
            }
        } else if ("INT".equals(attr)) {
            if (value instanceof Double) {
                if (((Double) value).isNaN()) {
                    ps.setObject(index + 1, null);
                } else {
                    ps.setInt(index + 1, ((Double) value).intValue());
                }
            } else {
                ps.setInt(index + 1, new Integer(value + ""));
            }
        } else if ("BOOLEAN".equals(attr)) {
            ps.setBoolean(index + 1, JsTypeUtil.isTrue(arg));
        } else if ("DOUBLE".equals(attr)) {
            if (value instanceof Double) {
                if (((Double) value).isNaN()) {
                    ps.setObject(index + 1, null);
                } else {
                    ps.setDouble(index + 1, (double) value);
                }
            } else {
                ps.setDouble(index + 1, new Double(value + ""));
            }
        } else if ("FLOAT".equals(attr)) {
            if (value instanceof Double) {
                if (((Double) value).isNaN()) {
                    ps.setObject(index + 1, null);
                } else {
                    ps.setFloat(index + 1, (float) (double) value);
                }
            } else {
                ps.setFloat(index + 1, new Float(value + ""));
            }
        } else if ("DATE".equals(attr)) {
            ps.setTimestamp(index + 1, parseDate(value));
        } else if ("TIME".equals(attr)) {
            ps.setTimestamp(index + 1, parseTime(value));
        } else if ("BINARY".equals(attr)) {
            ps.setBytes(index + 1, parseBinary(value));
        } else if ("CLOB".equals(attr)) {
            Clob clob = ps.getConnection().createClob();
            clob.setString(1, String.valueOf(value));
            ps.setClob(index + 1, clob);
        } else if ("LONG".equals(attr)) {
            if (value instanceof Double) {
                if (((Double) value).isNaN()) {
                    ps.setObject(index + 1, null);
                } else {
                    ps.setLong(index + 1, ((Double) value).longValue());
                }
            } else {
                ps.setLong(index + 1, new Long(value + ""));
            }
        } else if ("OUTCURSOR".equals(attr)) {
            // cs.registerOutParameter(i+1, OracleTypes.CURSOR);
            cs.registerOutParameter(index + 1, -10);
        } else if ("ARRAY".equals(attr)) {
            if (value instanceof NativeArray) {
                ps.setArray(index + 1, createSqlArray(ps.getConnection(), (NativeArray) value));
            } else {
                setArg(ps, index, value); // value is {ARRAY : ['int', e1, e2, ...]}
            }
            // ps.setObject(i+1, createSqlArray(ps.getConnection(),
            // (NativeArray) value));
        } else if ("JSON".equals(attr) || "JSONB".equals(attr)) {
            PGobject obj = new PGobject();
            obj.setType(attr.toLowerCase());
            obj.setValue(this.JSON.tryStringify(value));
            ps.setObject(index + 1, obj);
        } else if ("UUID".equals(attr)) {
            if (value != null) {
                ps.setObject(index + 1, UUID.fromString(value.toString()));
            } else {
                ps.setObject(index + 1, null);
            }
        } else {
            if (this.defaultJsonDbType != null) {
                PGobject obj = new PGobject();
                obj.setType(this.defaultJsonDbType);
                obj.setValue(this.JSON.tryStringify(arg));
                ps.setObject(index + 1, obj);
            } else {
                throw new SqlExecutorException("js argument " + arg + " (" + arg.getClass() + ") not support");
            }
        }
    } else {
        throw new SqlExecutorException(
                "js argument " + arg + " (" + arg.getClass() + ") at " + index + " not support");
    }
}

From source file:com.feedzai.commons.sql.abstraction.engine.impl.OracleEngine.java

@Override
protected int entityToPreparedStatement(final DbEntity entity, final PreparedStatement ps,
        final EntityEntry entry, final boolean useAutoInc) throws DatabaseEngineException {
    int i = 1;//from   ww  w.j  a  va 2s .c  o  m
    for (DbColumn column : entity.getColumns()) {
        if (column.isAutoInc() && useAutoInc) {
            continue;
        }

        try {
            final Object val;
            if (column.isDefaultValueSet() && !entry.containsKey(column.getName())) {
                val = column.getDefaultValue().getConstant();
            } else {
                val = entry.get(column.getName());
            }
            switch (column.getDbColumnType()) {
            case BLOB:
                ps.setBytes(i, objectToArray(val));

                break;
            case CLOB:
                if (val == null) {
                    ps.setNull(i, Types.CLOB);
                    break;
                }

                if (val instanceof String) {
                    StringReader sr = new StringReader((String) val);
                    ps.setClob(i, sr);
                } else {
                    throw new DatabaseEngineException("Cannot convert " + val.getClass().getSimpleName()
                            + " to String. CLOB columns only accept Strings.");
                }
                break;
            case BOOLEAN:
                Boolean b = (Boolean) val;
                if (b == null) {
                    ps.setObject(i, null);
                } else if (b) {
                    ps.setObject(i, "1");
                } else {
                    ps.setObject(i, "0");
                }

                break;
            default:
                ps.setObject(i, ensureNoUnderflow(val));
            }
        } catch (Exception ex) {
            throw new DatabaseEngineException("Error while mapping variables to database", ex);
        }

        i++;
    }

    return i - 1;
}

From source file:org.nuxeo.ecm.core.storage.sql.Mapper.java

/**
 * Gets the children ids and types of a node.
 */// w  ww  . j  av a  2 s .com
protected List<Serializable[]> getChildrenIds(Serializable id, boolean onlyComplex) throws SQLException {
    List<Serializable[]> childrenIds = new LinkedList<Serializable[]>();
    String sql = sqlInfo.getSelectChildrenIdsAndTypesSql(onlyComplex);
    if (isLogEnabled()) {
        logSQL(sql, Collections.singletonList(id));
    }
    List<Column> columns = sqlInfo.getSelectChildrenIdsAndTypesWhatColumns();
    PreparedStatement ps = connection.prepareStatement(sql);
    try {
        List<String> debugValues = null;
        if (isLogEnabled()) {
            debugValues = new LinkedList<String>();
        }
        ps.setObject(1, id); // parent id
        ResultSet rs = ps.executeQuery();
        while (rs.next()) {
            Serializable childId = null;
            Serializable childType = null;
            int i = 1;
            for (Column column : columns) {
                String key = column.getKey();
                Serializable value = column.getFromResultSet(rs, i++);
                if (key.equals(Model.MAIN_KEY)) {
                    childId = value;
                } else if (key.equals(Model.MAIN_PRIMARY_TYPE_KEY)) {
                    childType = value;
                }
            }
            childrenIds.add(new Serializable[] { childId, childType });
            if (debugValues != null) {
                debugValues.add(childId + "/" + childType);
            }
        }
        if (debugValues != null) {
            log("  -> " + debugValues);
        }
        return childrenIds;
    } finally {
        closePreparedStatement(ps);
    }
}