Hi Sander,

The correct handling of org.jooq.impl.Value.isChanged has become quite
tricky considering the various use-cases of setting values to a
record. In 2.0.x, I have implemented various tickets:

https://sourceforge.net/apps/trac/jooq/ticket/945
https://sourceforge.net/apps/trac/jooq/ticket/948
https://sourceforge.net/apps/trac/jooq/ticket/979

Some of these ticket arose from discussions with user Sergey Epik
(unfortunately, his e-mail was sent to me directly, not to the user
group):
https://groups.google.com/forum/#!msg/jooq-user/TYUg6XjPYlk/b1zTiNSwTYQJ

In essence, you can see here, that only "changed" values are actually set:
https://github.com/lukaseder/jOOQ/blob/master/jOOQ/src/main/java/org/jooq/impl/TableRecordImpl.java#L115

And values are considered as "changed" only if they are set explicitly:
https://github.com/lukaseder/jOOQ/blob/master/jOOQ/src/main/java/org/jooq/impl/Value.java#L70

But, when you set the value for the primary key, ALL values are set as
changed IF the primary key was modified in order to ensure that copied
records are fully inserted:
https://github.com/lukaseder/jOOQ/blob/master/jOOQ/src/main/java/org/jooq/impl/AbstractRecord.java#L186

You see the subtlety... So I'm guessing, you're setting the primary
key value explicitly, and that's why AbstractRecord:186 sets all
values of your record to "changed". Is that it? If so, then yes, it's
a regression of your use-case.

We have several options:

1. I fix this too and add more checks to see whether the primary key
has transitioned from "null" to "not null". In that case I might be
able to assume that the record was new and empty, and your use-case
probably applies. I'd have to think about this again, to be sure not
to break any other use cases.
2. You use a regular insert statement instead, which will give you
more fine-grained control over what is actually inserted
3. I add support for the "DEFAULT" clause in tables' DDL and
initialise generated source code records with that DEFAULT
4. I add support for the "DEFAULT" keyword in INSERT statements. There
would be a special DEFAULT flag in org.jooq.impl.Value of new records.
Whenever the "changed" flag transitions to "true", DEFAULT will
transition to "false". Copied records will not be reinitialised to
"DEFAULT" but might copy "DEFAULT" values from the original record.

I think that 4. might actually be the best option in order not to break #948:
https://sourceforge.net/apps/trac/jooq/ticket/948

The performance considerations of #948 are non-negligible in larger
systems. It is usually better to always set the same fields in INSERT
statements (regardless of their values), in order to keep databases'
cursor caches slim

Please, tell me what you think?

Cheers
Lukas

2012/1/10 Sander Plas <[email protected]>:
> Hi Lukas & others,
>
> Am i doing something wrong in my code or does jOOQ 2.0.1 and above set
> all non-defined columns in an INSERT statement to NULL again? This
> looks like a regression of bug #479.
>
> Sander

Reply via email to