запрос jooq с использованием переменных привязки

#sql #jdbc #jooq

#sql #jdbc #jooq

Вопрос:

Я использую переменную привязки для выполнения пакетного обновления, используя приведенный ниже код

 `var balanceUpdate = dslContext.batch(
                dslContext.update(BALANCE)
                .set(BALANCE.BALANCE, (BigDecimal) null)            
                .where(BALANCE.ID.eq((String) null)));
        balances.forEach(balance -> {
            balanceUpdate.bind(
                    balance.getAmount()
                    balance.Id);
        });
        int[] execute = balanceUpdate.execute();
 

`

Приведенный выше код работает хорошо, но теперь я хочу использовать bind с массивом аргументов, таких как

 var balanceUpdate = dslContext.batch(
                    dslContext.update(BALANCE)
                            .set(BALANCE.BALANCE, (BigDecimal) null)
                            .where(BALANCE.ID.eq((String) null)));
           
            var arguments = balances.stream()
                    .map(balance -> 
                                new Object[] {
                                 balance.getAmount(), 
                                 balance.Id
            }).collect(Collectors.toList());
            
            int[] execute = balanceUpdate.bind(arguments).execute();
 

Я получаю исключение

 java.lang.ArrayStoreException: arraycopy: element type mismatch: can not cast one of the elements of java.lang.Object[] to the type of the destination array, java.math.BigDecimal
    at org.jooq_3.14.4.ORACLE12C.debug(Unknown Source)
    at java.base/java.util.Arrays.copyOf(Arrays.java:3722)
    at org.jooq.tools.Convert.convertArray(Convert.java:357)
    at org.jooq.tools.Convert.convertArray(Convert.java:345)
    at org.jooq.tools.Convert$ConvertAll.from(Convert.java:603)
    at org.jooq.tools.Convert.convert0(Convert.java:392)
    at org.jooq.tools.Convert.convert(Convert.java:384)
    at org.jooq.tools.Convert.convert(Convert.java:458)
    at org.jooq.tools.Convert.convertArray(Convert.java:363)
    at org.jooq.tools.Convert.convertArray(Convert.java:345)
    at org.jooq.tools.Convert$ConvertAll.from(Convert.java:614)
    at org.jooq.tools.Convert.convert0(Convert.java:392)
    at org.jooq.tools.Convert.convert(Convert.java:384)
    at org.jooq.tools.Convert.convert(Convert.java:458)
    at org.jooq.impl.AbstractDataType.convert(AbstractDataType.java:534)
    at org.jooq.impl.DefaultDataType.convert(DefaultDataType.java:86)
    at org.jooq.impl.DSL.val(DSL.java:24409)
    at org.jooq.impl.DSL.val(DSL.java:24377)
    at org.jooq.impl.Tools.field(Tools.java:1794)
    at org.jooq.impl.Tools.fields(Tools.java:1865)
    at org.jooq.impl.BatchSingle.executePrepared(BatchSingle.java:226)
    at org.jooq.impl.BatchSingle.execute(BatchSingle.java:170)
 

Согласно документам, это должно работать? По крайней мере, он работает без явного приведения при использовании jdbc. Есть ли способ заставить его работать с отправленными переменными привязки только один раз, а не много раз, как в первом примере?

Ответ №1:

Я думаю, что вы вызываете неправильный BatchBindStep.bind(Object...) метод или, по крайней мере, не так, как вы ожидаете. В настоящее время нет перегрузки, принимающей коллекцию типа List<Object[]> . Итак, вместо этого вам следует создать Object[][] тип для ваших наборов переменных привязки:

 Object[][] arguments = balances
    .stream()
    .map(balance -> new Object[] {
        balance.getAmount(), 
        balance.Id
    }).toArray();