Lukas, On Fri, Oct 25, 2013 at 5:03 PM, Lukas Eder <[email protected]> wrote:
> Hi Daniele, > > > 2013/10/23 Daniele Antonini <[email protected]> > >> Lukas, >> >> On Wed, Oct 23, 2013 at 5:01 PM, Lukas Eder <[email protected]> wrote: >> >>> Hi Daniele, >>> >>> The rationale behind this is easy to explain: >>> >>> >>> PersonRecord p = //... select ...assert p.getName() == "Otto"; >>> >>> >>> >>> >>> >>> p.setName("Otto"); //why changed flag remains true? >>> p.store(); >>> >>> Explicitly setting a value in a record means that you want this value to >>> appear in an INSERT / UPDATE statement. This may have desired side-effects >>> on triggers and other database objects. Note that there is also >>> >>> >>> p.reset(); >>> >>> In order to reset the changed flags and the value. >>> >> Thanks, now it's clear. >> >> In my domain, I have no trigger, nor other database objects. I need only >> to store data into database, and I want to do this in efficient way and >> reduce database sql size may help. >> For my needed the best is to set only values that are effectively >> updated, since I use ModelMapper I'd rather have my domain object, map it >> to one or more records and invoke store(). >> I don't want to worry to know which fields are changed. >> >> I have implemented this beaviour with the following class: >> >> public class SetOnlyChangedValueAccountUserRecord implements IAccountUser >> { >> private static boolean equals(final Object orig, final Object current) { >> if (orig == current) { return true; } >> if (orig != null && current != null) { return orig.equals(current); } >> return false; >> } >> private IAccountUser delegate; >> private IAccountUser orig; >> >> public SetOnlyChangedValueAccountUserRecord(final AccountUserRecord r) { >> delegate = r; >> orig = r.original(); >> } >> @Override >> public void setEmail(final String value) { >> if (!equals(orig.getEmail(), value)) { >> delegate.setEmail(value); >> } >> } >> //other set, get , and other stuff >> } >> >> Same result can be obtained with a proxy class, using a bit of >> reflection, to make this "solution" general purpose. >> Do you think such utility class should be part of JOOQ, or developed when >> needed from developer? >> > > I'm not sure if your proxy is correct. Let's assume this control flow: > > assertEquals("x", user.getEmail()); > > user.setEmail("x"); // This has no effect > > user.setEmail("y"); // This sets email to "y" > user.setEmail("x"); // This has no effect (!) > > > I think you shouldn't compare the new value with orig.getEmail() value > but with delegate.getEmail() instead. Or even better, this: > > delegate.setEmail(value); > if (equals(orig.getEmail(), value)) { > delegate.changed(ACCOUNT_USER.EMAIL, false); > } > Also, calls to user.setValue(ACCOUNT_USER.EMAIL, "y") are not intercepted. > This might be irrelevant if you only expose the interface that contains > setters and getters, not the jOOQ record. > You're right, I have blundered :) > > I agree that it might be nice to be able to influence whether assigning > the same value again to a Record should set the changed flag to true. I > think that this behaviour should be adaptable through a Setting, though. > There is a feature request pending for jOOQ 3.3: > https://github.com/jOOQ/jOOQ/issues/2704 > Ok, happy to be useful Cheers > > > Cheers > Lukas > > >> >> >> More comments inline: >>> >>> 2013/10/23 Daniele Antonini <[email protected]> >>> >>>> Hi, >>>> >>>> I'm playing a bit with UpdatableRecords, and I'm falling into this >>>> issue: primary key is marked as changed also when setted value is the same >>>> of prevoius one. >>>> >>>> I wirte a test to reproduced the issue: >>>> 1) using set<columnName> of generated record >>>> 2) using ModelMapper (corresponds to the previous case because it uses >>>> generated set) >>>> >>>> This test fails: >>>> @Test public void test() { >>>> AccountUserRecord r = ctx.fetchOne(ACCOUNT_USER, >>>> ACCOUNT_USER.ID.eq(1L)); >>>> r.setId(1L); >>>> assertFalse(r.changed(ACCOUNT_USER.ID)); >>>> } >>>> >>>> When I use setValue(Field, value) the behaviour is correct, as a matter >>>> of fact this test pass: >>>> @Test public void test() { >>>> AccountUserRecord r = ctx.fetchOne(ACCOUNT_USER, >>>> ACCOUNT_USER.ID.eq(1L)); >>>> r.setValue(ACCOUNT_USER.ID, 1L); >>>> assertFalse(r.changed(ACCOUNT_USER.ID)); >>>> } >>>> >>> >>> Hmm, yes there's a bug in the above behaviour. The two calls are not >>> exactly equivalent, which is not good. I'll investigate this: >>> https://github.com/jOOQ/jOOQ/issues/2798 >>> >>> >>>> For completeness' sake I attached a full maven project to highlight the >>>> problem, the project require mysql. >>>> >>>> Generated AccountUserRecord.setId is the following code: >>>> public void setId(java.lang.Long value) { >>>> setValue(0, value); >>>> } >>>> >>>> Why use setValue(int, value) instead of setValue(Field, value)? >>>> >>> >>> Internally, records use field indexes, not Field references. So this >>> call is a bit more performant than setValue(Field, value). But the logic >>> should still be the same (which will be investigated in #2798) >>> >> Ok >> >> Hope this helps >>> >> Cheers >>> Lukas >>> >>> >>>> Is this an issue of code generator? >>>> >>>> I read https://github.com/jOOQ/jOOQ/issues/945?source=c and >>>> https://github.com/jOOQ/jOOQ/issues/948 but I'm still puzzled: >>>> >>>> PersonRecord p = //... select ...assert p.getName() == >>>> "Otto";p.setName("Max"); //ok changed is truep.setName("Max"); // ok >>>> changed is still true, change flag is not resettedp.setName("Otto"); //why >>>> changed flag remains true? p.store(); >>>> >>>> >>>> Cheers >>>> >>>> -- >>>> Daniele >>>> >>> >> Cheers >> -- >> Daniele >> >> -- >> You received this message because you are subscribed to the Google Groups >> "jOOQ User Group" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected]. >> For more options, visit https://groups.google.com/groups/opt_out. >> > > -- > You received this message because you are subscribed to a topic in the > Google Groups "jOOQ User Group" group. > To unsubscribe from this topic, visit > https://groups.google.com/d/topic/jooq-user/gtMxNzg02NA/unsubscribe. > To unsubscribe from this group and all its topics, send an email to > [email protected]. > For more options, visit https://groups.google.com/groups/opt_out. > -- Daniele -- You received this message because you are subscribed to the Google Groups "jOOQ User Group" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/groups/opt_out.
