如何 return 触发器为 JOOQ 记录存储创建的值?
How to return values created by trigger for JOOQ record store?
几个星期以来,我们使用 JOOQ 作为我们的主要持久性框架,而不是所有那些 Spring 数据 JPA/Hibernate 东西。我真的很感动!!!
对于简单的 CRUD 操作,我们使用 record.store()
并且由于底层 table 包含一个 ID(列 id
,PostgreSQL 类型 serial
) 此外,JOOQ 配置有 withReturnAllOnUpdatableRecord(true)
并且我们的 table 包含一个触发器来为列 nummer
:
生成值
CREATE OR REPLACE FUNCTION "public"."after_insert_angebot" () RETURNS trigger
VOLATILE
AS $body$
DECLARE
BEGIN
UPDATE kalkulation_angebot SET nummer = date_part('year', CURRENT_DATE) || '-' || LPAD(NEW.id::text, 3, '0') WHERE id = NEW.id;
RETURN NEW;
END;
$body$ LANGUAGE plpgsql
CREATE TRIGGER "after_insert_angebot"
AFTER INSERT ON kalkulation_angebot
FOR EACH ROW
EXECUTE PROCEDURE after_insert_angebot()
我预计,在 record.store()
之后并且由于 withReturnAllOnUpdatableRecord(true)
,记录包含 id(由列类型生成)和 nummer(由触发器生成)的值。但只有 id
被填充。我必须通过额外的查询手动设置 nummer
:
// jooq fetched the new values and the id is available
Integer angebotId = record.getId();
// ... but nummer is missing and has to set manually
angebot.setNummer(jooq.select(KALKULATION_ANGEBOT.NUMMER)
.from(KALKULATION_ANGEBOT)
.where(KALKULATION_ANGEBOT.ID.eq(record.getId()))
.fetchSingleInto(String.class));
我假设错误是在触发函数内?触发器应该如何,以实现文档的承诺:
The identity value is not the only value that is generated by default. Specifically, there may be triggers that are used for [...] Users who wish to also automatically fetch these values after all store(), insert(), or update() calls may do so by specifying the returnAllOnUpdatableRecord setting
提前致谢
多米尼克
设置 withReturnAllOnUpdatableRecord(true)
在 jOOQ 中生成 INSERT .. RETURNING
或 UPDATE .. RETURNING
语句。由于您已经定义了一个 AFTER INSERT
触发器,因此这无助于返回您可能期望的值。在 vanilla PostgreSQL 中尝试:
CREATE TABLE kalkulation_angebot (
id serial,
nummer text
);
-- Your own TRIGGER below:
CREATE OR REPLACE FUNCTION "public"."after_insert_angebot" () RETURNS trigger
VOLATILE
AS $body$
BEGIN
UPDATE kalkulation_angebot
SET nummer = date_part('year', CURRENT_DATE) || '-' || LPAD(NEW.id::text, 3, '0')
WHERE id = NEW.id;
RETURN NEW;
END;
$body$ LANGUAGE plpgsql;
CREATE TRIGGER "after_insert_angebot"
AFTER INSERT ON kalkulation_angebot
FOR EACH ROW EXECUTE PROCEDURE after_insert_angebot();
INSERT INTO kalkulation_angebot DEFAULT VALUES RETURNING *;
输出为:
|id |nummer |
|-----------|--------|
|1 | |
你把你的触发器换成我认为更有意义的东西怎么样:
CREATE OR REPLACE FUNCTION "public"."before_insert_angebot" () RETURNS trigger
VOLATILE
AS $body$
BEGIN
NEW.nummer = date_part('year', CURRENT_DATE) || '-' || LPAD(NEW.id::text, 3, '0');
RETURN NEW;
END;
$body$ LANGUAGE plpgsql;
CREATE TRIGGER "before_insert_angebot"
BEFORE INSERT ON kalkulation_angebot
FOR EACH ROW EXECUTE PROCEDURE before_insert_angebot();
INSERT INTO kalkulation_angebot DEFAULT VALUES RETURNING *;
现在的输出是:
|id |nummer |
|-----------|--------|
|1 |2020-001|
几个星期以来,我们使用 JOOQ 作为我们的主要持久性框架,而不是所有那些 Spring 数据 JPA/Hibernate 东西。我真的很感动!!!
对于简单的 CRUD 操作,我们使用 record.store()
并且由于底层 table 包含一个 ID(列 id
,PostgreSQL 类型 serial
) 此外,JOOQ 配置有 withReturnAllOnUpdatableRecord(true)
并且我们的 table 包含一个触发器来为列 nummer
:
CREATE OR REPLACE FUNCTION "public"."after_insert_angebot" () RETURNS trigger
VOLATILE
AS $body$
DECLARE
BEGIN
UPDATE kalkulation_angebot SET nummer = date_part('year', CURRENT_DATE) || '-' || LPAD(NEW.id::text, 3, '0') WHERE id = NEW.id;
RETURN NEW;
END;
$body$ LANGUAGE plpgsql
CREATE TRIGGER "after_insert_angebot"
AFTER INSERT ON kalkulation_angebot
FOR EACH ROW
EXECUTE PROCEDURE after_insert_angebot()
我预计,在 record.store()
之后并且由于 withReturnAllOnUpdatableRecord(true)
,记录包含 id(由列类型生成)和 nummer(由触发器生成)的值。但只有 id
被填充。我必须通过额外的查询手动设置 nummer
:
// jooq fetched the new values and the id is available
Integer angebotId = record.getId();
// ... but nummer is missing and has to set manually
angebot.setNummer(jooq.select(KALKULATION_ANGEBOT.NUMMER)
.from(KALKULATION_ANGEBOT)
.where(KALKULATION_ANGEBOT.ID.eq(record.getId()))
.fetchSingleInto(String.class));
我假设错误是在触发函数内?触发器应该如何,以实现文档的承诺:
The identity value is not the only value that is generated by default. Specifically, there may be triggers that are used for [...] Users who wish to also automatically fetch these values after all store(), insert(), or update() calls may do so by specifying the returnAllOnUpdatableRecord setting
提前致谢
多米尼克
设置 withReturnAllOnUpdatableRecord(true)
在 jOOQ 中生成 INSERT .. RETURNING
或 UPDATE .. RETURNING
语句。由于您已经定义了一个 AFTER INSERT
触发器,因此这无助于返回您可能期望的值。在 vanilla PostgreSQL 中尝试:
CREATE TABLE kalkulation_angebot (
id serial,
nummer text
);
-- Your own TRIGGER below:
CREATE OR REPLACE FUNCTION "public"."after_insert_angebot" () RETURNS trigger
VOLATILE
AS $body$
BEGIN
UPDATE kalkulation_angebot
SET nummer = date_part('year', CURRENT_DATE) || '-' || LPAD(NEW.id::text, 3, '0')
WHERE id = NEW.id;
RETURN NEW;
END;
$body$ LANGUAGE plpgsql;
CREATE TRIGGER "after_insert_angebot"
AFTER INSERT ON kalkulation_angebot
FOR EACH ROW EXECUTE PROCEDURE after_insert_angebot();
INSERT INTO kalkulation_angebot DEFAULT VALUES RETURNING *;
输出为:
|id |nummer |
|-----------|--------|
|1 | |
你把你的触发器换成我认为更有意义的东西怎么样:
CREATE OR REPLACE FUNCTION "public"."before_insert_angebot" () RETURNS trigger
VOLATILE
AS $body$
BEGIN
NEW.nummer = date_part('year', CURRENT_DATE) || '-' || LPAD(NEW.id::text, 3, '0');
RETURN NEW;
END;
$body$ LANGUAGE plpgsql;
CREATE TRIGGER "before_insert_angebot"
BEFORE INSERT ON kalkulation_angebot
FOR EACH ROW EXECUTE PROCEDURE before_insert_angebot();
INSERT INTO kalkulation_angebot DEFAULT VALUES RETURNING *;
现在的输出是:
|id |nummer |
|-----------|--------|
|1 |2020-001|