поля в записи JOOQ не выстраиваются, когда fetchInto - PullRequest
0 голосов
/ 09 ноября 2018

Это странная проблема, которая постоянно возникает в версиях 3.10 и 3.11 JOOQ (не пробовала более ранние версии). Я выбираю запись, используя fetchInto, и когда я печатаю запись (или выполняю отладку), все поля печатаются правильно. То есть значение для field_x является правильным.

Проблема в том, что когда я иду к извлечению field_x с использованием метода getX записи, он возвращает значение из другого поля.

Ниже приведен код, который мы использовали.

        return jooqDslContext.select(CL_USERS.fields())
            .from(CL_USERS)
            .join(THIRDPARTY_USER_XREF)
            .on(THIRDPARTY_USER_XREF.USER_ID.eq(CL_USERS.CL_USER_ID))
            .join(THIRDPARTY_USER_ID)
            .on(THIRDPARTY_USER_ID.ID.eq(THIRDPARTY_USER_XREF.THIRDPARTY_ID))
            .where(THIRDPARTY_USER_ID.EID.eq(eid))
            .fetchOptionalInto(CL_USERS);

Вот распечатка записи ...

+--------------------------------------------------+----------+------+-----------+------------------+------------+----------------+------------------------+ etc... 
|remember_token                                    |cl_user_id|ria_id|ria_user_id|ria_user_id_backup|cl_user_type|user_description|first_name              | etc...
+--------------------------------------------------+----------+------+-----------+------------------+------------+----------------+------------------------+ etc...
|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...| 777777777|   777|      77777|            {null}|      {null}|{null}          |xxxxxxxxxxxxxxxxxxxxxxxx| etc...
+--------------------------------------------------+----------+------+-----------+------------------+------------+----------------+------------------------

обратите внимание, что first_name заполнен. но когда я печатаю first_name с использованием метода getFirstName, я получаю NULL.

cur.getFirstName() = null

Судя по всему, существует несоответствие между порядковым номером поля .... сгенерированный код считает, что firstName - это поле 6, в данном случае, но на самом деле это поле 8 (восьмое поле на выходе toString().

    public byte[] getFirstName() {
        return (byte[]) get(6);
    }

РЕДАКТИРОВАТЬ: Добавление дополнительной информации.

Как это можно воспроизвести?

Вот еще один пример, использующий кодовую базу, отличную от приведенной выше. В этом случае я установил поле amount на объекте записи. Но когда я иду сохранить или распечатать, вместо этого устанавливается поле address.

    TransactionsRecord tr = serviceDslContext.newRecord(Transactions.TRANSACTIONS);
    tr.setAmount(new BigDecimal(10));
    logger.debug("tr = {}", tr);

печать ..

+------+-------+-------+...
|amount|account|address|...
+------+-------+-------+...
|{null}|{null} |*10    |...
+------+-------+-------+...

Ссылка на сгенерированный код JOOQ.

Можете ли вы опубликовать DDL таблицы?

CREATE TABLE `transactions` (
    `account` VARCHAR(50) NOT NULL,
    `address` VARCHAR(50) NOT NULL,
    `amount` DECIMAL(42,10) NOT NULL,
    `bip125-replaceable` VARCHAR(64) NOT NULL,
    `blockhash` VARCHAR(64) NOT NULL,
    `blockindex` INT(11) NOT NULL,
    `blocktime` TIMESTAMP NULL DEFAULT NULL,
    `category` VARCHAR(50) NOT NULL,
    `confirmation` INT(11) NOT NULL,
    `generated` TINYINT(1) NOT NULL,
    `instantlock` TINYINT(4) NOT NULL,
    `involvesWatchonly` TINYINT(4) NOT NULL,
    `label` VARCHAR(50) NOT NULL,
    `time` TIMESTAMP NULL DEFAULT NULL,
    `timereceived` TIMESTAMP NULL DEFAULT NULL,
    `txid` VARCHAR(64) NOT NULL,
    `vout` INT(11) NOT NULL,
    `walletconflicts` TEXT NULL,
    `amount_in_usd` DECIMAL(42,10) NULL DEFAULT NULL,
    `usd_exchange_rate` DECIMAL(42,10) NULL DEFAULT NULL,
    PRIMARY KEY (`txid`),
    INDEX `account_generated` (`account`, `generated`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
;

Какой продукт и версию базы данных вы используете?

В вышеупомянутом случае я использую MySQL 5.7.23 на AWS RDS. Для первого примера это был вариант MySQL 5.6 на AWS RDS. Кроме того, в последнем примере это произошло на 5.7.14-google, мы недавно перешли на AWS.

Ответы [ 2 ]

0 голосов
/ 15 ноября 2018

После некоторого тестирования похоже, что функция Rearrange code в IntelliJ испортила сгенерированный JOOQ код. Это может иметь тяжелые последствия для кода, работающего в производстве. Функция Rearrange code отображается в качестве параметра в окне «Принять изменения».

enter image description here

Тестирование состояло из запуска теста до и после функции Rearrange code. Ниже приведен код.

    TransactionsRecord tr = serviceDslContext.newRecord(TRANSACTIONS);
    tr.setAmount(new BigDecimal(10));
    logger.debug("tr = {}", tr);

Если этот код выполняется до функции Rearrange code, то есть сразу после того, как JOOQ сгенерировал код, то отображается следующее ...

 +-------+-------+------+...
|account|address|amount|...
+-------+-------+------+...
|{null} |{null} |   *10|...
+-------+-------+------+...

После того, как IntelliJ выполнит Rearrange code в сгенерированном коде JOOQ, это будет вывод ...

+------+-------+-------+...
|amount|account|address|...
+------+-------+-------+...
|{null}|{null} |*10    |...
+------+-------+-------+...

Кажется, что значения остаются в правильном месте, но поля, которые представляют эти значения, сместились вокруг.

0 голосов
/ 13 ноября 2018

Похоже, что созданная вами запись была изменена вручную или с использованием некоторых постпроцессоров, или она была сгенерирована специальным генератором. Понятно, сгенерированная таблица (правильный порядок):

public class Transactions extends TableImpl<TransactionsRecord> {

    ...

    public final TableField<TransactionsRecord, BigDecimal> AMOUNT = 
      createField("amount", org.jooq.impl.SQLDataType.DECIMAL(42, 10).nullable(false), this, "");

    public final TableField<TransactionsRecord, String> ACCOUNT = 
      createField("account", org.jooq.impl.SQLDataType.VARCHAR(50).nullable(false), this, "");

    public final TableField<TransactionsRecord, String> ADDRESS = 
      createField("address", org.jooq.impl.SQLDataType.VARCHAR(50).nullable(false), this, "");

    ...

... и сгенерированная запись:

public class TransactionsRecord extends UpdatableRecordImpl<TransactionsRecord> 
    implements Record20<...> {

    public void setAccount(String value) {
        set(0, value);
    }

    public String getAccount() {
        return (String) get(0);
    }

    public void setAddress(String value) {
        set(1, value);
    }

    public TransactionsRecord() {
        super(Transactions.TRANSACTIONS);
    }

    public TransactionsRecord(String account, String address, BigDecimal amount, ...) {
        super(Transactions.TRANSACTIONS);

        set(0, account);
        set(1, address);
        set(2, amount);
        ...
    }

    public BigDecimal getAmount() {
        return (BigDecimal) get(2);
    }

    public String getAddress() {
        return (String) get(1);
    }

    public void setAmount(BigDecimal value) {
        set(2, value);
    }

    public void setBlockhash(String value) {
        set(4, value);
    }

    ...

... не совпадают. Посмотрите, как существуют геттеры и сеттеры до и после конструктора. Кроме того, они не в порядке! Официальный JavaGenerator, предоставленный jOOQ, не будет генерировать такой класс.

Обратите внимание: если вы хотите изменить сгенерированный код, вы должны либо переопределить JavaGenerator, либо реализовать свой собственный класс генератора.

...