Обновите с помощью «в случае конфликта сделайте обновление» с частичным индексом в jOOQ

#postgresql #jooq

Вопрос:

У меня есть частичный индекс в таблице MY_TABLE , который определяется следующим образом:

 CREATE UNIQUE INDEX my_index 
    ON MY_TABLE(CUSTOMER_ID, OWNER_ID) 
    WHERE CLOSED_ON IS NULL;
 

Затем я пытаюсь поднять, используя jOOQ

 final var insert = using(configuration)
           .insertInto(MY_TABLE,
                       MY_TABLE.CUSTOMER_ID,
                       MY_TABLE.OWNER_ID,
                       MY_TABLE.UPDATED_ON);
customers.forEach(custId -> insert.values(custId, reprId, today));
insert.onConflict(MY_TABLE.CUSTOMER_ID, MY_TABLE.OWNER_ID)
    .where(MY_TABLE.CLOSED_ON.isNull())
    .doUpdate()
    .set(MY_TABLE.UPDATED_ON, today)
    .execute();
 

Но приведенный выше код выдает эту ошибку:

 org.jooq.exception.DataAccessException: SQL [...];
   ERROR: invalid reference to FROM-clause entry for table "my_table"
   Hint: There is an entry for table "my_table", but it cannot be referenced from this part of the query.
 

Глядя на сгенерированный SQL , я вижу, что jOOQ добавляет схему и имя таблицы в ту where часть on conflict , которая не нравится Postgres:

 ... on conflict ("customer_id", "owner_id") where "my_schema"."my_table"."closed_on" is null do update set ...
 

Есть ли способ сказать jOOQ, чтобы он не добавлял схему и имя таблицы?

Это обходной путь, который я использую, но мне интересно, есть ли лучший способ:

 .where(condition("closed_on IS NULL"))
 

Ответ №1:

Мы нашли сообщение об ошибке на странице проблем jOOQ, в котором задается именно этот вопрос:

https://github.com/jOOQ/jOOQ/issues/11732

В котором упоминается этот обходной путь:

 .where(field(COURSE_ENROLL.DELETED_TS.getUnqualifiedName()).isNull())
 

Так что я могу сделать это вместо того, что я сделал с буквальной строкой в моем случае.

Это также упоминается как ошибка, которая была исправлена 3 недели назад 🙂

Спасибо.

ИЗМЕНИТЬ: Для этого уже есть исправление в jOOQ 3.14.9

Комментарии:

1. Спасибо, в итоге я действительно использовал 3.14.9