jOOQ / jOOQ

jOOQ is the best way to write SQL in Java
https://www.jooq.org
Other
6.15k stars 1.21k forks source link

Cannot call Record.reset(Field), Record.original(Field), Record.changed(Field), Record.touched(Field), Record.modified(Field) with embeddable field arguments #17433

Closed Rattenkrieg closed 5 days ago

Rattenkrieg commented 6 days ago

Expected behavior

I have an embeddable composite field consisting of two columns. I get IllegalArgumentException when I try to reset this field in the record

MCVE: https://github.com/Rattenkrieg/jOOQ-mcve/pull/1/files

Actual behavior

 IllegalArgument Field "mcve"."composite_key_example"."entity_1_id", "mcve"."composite_key_example"."entity_2_id" is not contained in row type ("mcve"."composite_key_example"."entity_1_id", "mcve"."composite_key_example"."entity_2_id", "mcve"."composite_key_example"."some_payload")

Steps to reproduce the problem


CompositeKeyExampleRecord record = ctx.fetchOne(COMPOSITE_KEY_EXAMPLE, COMPOSITE_KEY_EXAMPLE.ENTITY_1_ID.eq(1));
record.reset(COMPOSITE_KEY_EXAMPLE.COMPOSITE_ID);

CREATE TABLE mcve.composite_key_example (
  entity_1_id INT NOT NULL,
  entity_2_id INT NOT NULL,
  some_payload TEXT NOT NULL
);

ALTER TABLE mcve.composite_key_example ADD PRIMARY KEY (entity_1_id, entity_2_id);
<generator>
    <database>
        <includes>.*</includes>
        <schemata>

            <!-- PostgreSQL is lower case by default -->
            <schema>
                <inputSchema>mcve</inputSchema>
            </schema>
        </schemata>

        <embeddables>
        <embeddable>
            <catalog/>
            <schema>mvce</schema>
            <name>composite_key_example_id</name>
            <referencingName>composite_id</referencingName>
            <tables>composite_key_example</tables>
            <fields>
                <field><expression>entity_1_id</expression></field>
                <field><expression>entity_2_id</expression></field>
            </fields>
        </embeddable>
        </embeddables>
    </database>
    <generate>
        <generatedAnnotation>false</generatedAnnotation>
    </generate>
    <target>
        <packageName>org.jooq.mcve.java.postgres</packageName>
        <directory>src/main/java</directory>
    </target>
</generator>

jOOQ Version

Open source edition 3.19.13

Database product and version

postgres:latest

Java Version

openjdk 21

JDBC / R2DBC driver name and version (include name if unofficial driver)

org.postgresql:postgresql:42.7.2

lukaseder commented 5 days ago

Thanks a lot for your report. I can see how this could be reasonably expected to work, given that setters and getters allow this call as well for non-replacing embeddables. Things work as expected with replacing embeddables, including embedded keys: https://www.jooq.org/doc/latest/manual/code-generation/codegen-embeddable-types/codegen-embedded-keys/

lukaseder commented 5 days ago

With non-replacing embeddables, the workaround is to simply iterate over the embeddable's fields and to reset them individually.

lukaseder commented 5 days ago

The Record.original(Field) and Record.touched(Field) (previously Record.changed(Field)) methods are also affected

Rattenkrieg commented 5 days ago

With non-replacing embeddables, the workaround is to simply iterate over the embeddable's fields and to reset them individually.

Yep, this is how I patched if for now

/// works
for (var field : COMPOSITE_KEY_EXAMPLE.COMPOSITE_ID.getTable().fields()) {
    record.reset(field);
}

Thank you!

lukaseder commented 5 days ago

Fixed in versions: