Adding a little to this tangent on a tangent, I got the postgres driver to 
transfer/read UUID column values as binary, using:

((PgConnection)connection).setForceBinary( true );

This can also be enabled using the driver option ?prepareThreshold=-1 (as seen 
in the driver documentation at https://jdbc.postgresql.org/documentation/use/ ).

Not recommending any of this, just reporting what I've found in case anyone is 
interested (although it initially seems to work fine, after some rudimentary 
testing on my own projects — and should be a performance boon, even if we're 
still doing the string-thing on the Cayenne side). Not using binary transfer 
wherever possible feels like a waste of resources, and apparently I'm not the 
first guy to wonder, threre's some more speculation/discussion here from people 
more in the know: https://postgrespro.com/list/thread-id/2599310 .

Cheers,
- hugi



> On 27 Aug 2024, at 09:14, Hugi Thordarson <h...@godurkodi.is> wrote:
> 
> Ah! Interesting.
> 
> Just about every entity in all of my projects has a uniqueID attribute mapped 
> to a UUID-typed field in postgres (with type OTHER/java.util.UUID in the 
> cayenne model). It's not the PK, just an identifier used to reference the row 
> in things like URLs, REST apis and other places where you really don't want 
> to expose your serial PKs.
> 
> Always worked like a charm and I never thought much about how these values 
> were actually processed by the stack. But looking at a fetch, I'm seeing the 
> value does indeed get processed as a string by Cayenne and is converted from 
> the string representation to a UUID.
> 
> However, doing some more testing on the UUID field using plain JDBC shows 
> that the postgres driver itself also seems to fetch/process the UUID as a 
> string. If you invoke ResultSet.getObject( ... ) the postgres JDBC driver 
> will go here:
> 
> https://github.com/pgjdbc/pgjdbc/blob/e33be5c0481c22f4242a5d7ef2d2c09c8a17179f/pgjdbc/src/main/java/org/postgresql/jdbc/PgResultSet.java#L270-L275
> 
> … and at least in my case, this always fails the isBinary() check and 
> proceeds to getString(...) . Now wondering how to get the JDBC driver to 
> fetch/process the UUID column as a binary value (which, judging from that 
> driver method *should* be doable), saving some bytes along the way.
> 
> Might take a second look tonight. But on the other hand, I think I'm deeper 
> into JDBC than ever before at this point and not sure I'm on the right path 
> so I should probably be stopped. But this is fun :).
> 
> Cheers,
> - hugi
> 
> 
> 
> 
>> On 26 Aug 2024, at 19:05, Andrus Adamchik <aadamc...@gmail.com> wrote:
>> 
>> And another hole in Cayenne UUID support... We have this:
>> 
>> UUIDValueType implements ValueObjectType<UUID, String>
>> 
>> but not this that is required to handle UUID mapping to binary columns:
>> 
>> UUIDValueType implements ValueObjectType<UUID, byte[]>
>> 
>> I am going to write the latter for my own needs, and will try to fold it 
>> back to Cayenne.
>> 
>> A.
>> 
>> 
>>> On Aug 26, 2024, at 9:30 AM, Andrus Adamchik <aadamc...@gmail.com> wrote:
>>> 
>>> Yep. The IDUtil-returned sequence is not an RFC-compliant UUID. It is kind 
>>> of our own invention. We can change it to a formal UUID. Though Java still 
>>> doesn't support UUIDv7, which is bummer. Wonder how easy is is to write a 
>>> UUIDv7 generator on our own?
>>> 
>>> While we are on this topic, my pet peeve about PK generation is the opaque 
>>> "Cayenne-Generated" strategy in the Modeler. Its original motivation was to 
>>> dynamically provide an optimal strategy for a specific database, 
>>> considering widely differing DB capabilities. Now all databases can do 
>>> everything, so this strategy is just confusing. It should be expanded into 
>>> a list of specific strategies (PK table, PK procedure, PK sequence, UUID). 
>>> Each one can have its own implementation per DbAdapter.
>>> 
>>> Andrus
>>> 
>>>> On Aug 26, 2024, at 7:24 AM, Jurgen Doll <jur...@ivoryemr.co.za> wrote:
>>>> 
>>>> Hi Michael
>>>> 
>>>> So Cayenne actually currently does support generating UUID PK's, if in the 
>>>> Cayenne Modeler you:
>>>> 
>>>> 1. set your column type to BINARY
>>>> 2. set it to a length of 16
>>>> 3. check the PK flag, and
>>>> 4. set the table's "PK Generation Strategy" to Cayenne
>>>> 
>>>> This will result in a UUID being generated via 
>>>> "org.apache.cayenne.util.IDUtil.pseudoUniqueSecureByteSequence(int)".
>>>> 
>>>> Unfortunately this UUID is currently a MD5 digest which is bad for 
>>>> indexing.
>>>> 
>>>> The reason for the digest is to anonymise the underlying UUID which is 16 
>>>> bytes long consisting of:
>>>> bytes 0..3 - incrementing #
>>>> bytes 4..11 - timestamp
>>>> bytes 12..15 - IP address
>>>> 
>>>> The above UUID generation could easily be changed to use Java's native 
>>>> UUID which is a Time-Based UUID that would be index friendly, if I'm not 
>>>> mistaken.
>>>> 
>>>> Regards
>>>> Jurgen
>>>> 
>>>> 
>>>> On Sat, 24 Aug 2024 04:42:39 +0200, Michael Gentry <blackn...@gmail.com> 
>>>> wrote:
>>>> 
>>>>> Hi Andrus,
>>>>> 
>>>>> Part of what I meant by adding UUID support to Cayenne was to include  
>>>>> UUID
>>>>> as a PK mechanism in Cayenne modeler and provide a corresponding PK
>>>>> generator class. Nothing currently stops you from manually setting a UUID
>>>>> yourself, but including support in the modeler would be a more natural 
>>>>> fit, I think.
>>>>> 
>>>>> Thanks,
>>>>> mrg
>>>>> 
>>>>> 
>>>>> On Fri, Aug 23, 2024 at 4:33 PM Andrus Adamchik <aadamc...@gmail.com> 
>>>>> wrote:
>>>>> 
>>>>>> I am actually glad we went on a tangent and started discussing UUIDs. I
>>>>>> just ran into a use-case of an idempotent PUT API endpoint that takes a 
>>>>>> mix
>>>>>> of new and existing objects, and there's no natural key in the entity to
>>>>>> check whether new (PK-less) objects are already in DB (so that we UPDATE
>>>>>> them instead of INSERT). UUID would come in handy in this situation :)
>>>>>> 
>>>>>> (FWIW, the endpoint is running on Agrest with Cayenne underneath, and
>>>>>> Agrest is the layer that ensures idempotent semantics).
>>>>>> 
>>>>>> Andrus
>>>>>> 
>>>>>> 
>>>>>>> On Aug 20, 2024, at 12:01 PM, Hugi Thordarson <h...@godurkodi.is> wrote:
>>>>>>> 
>>>>>>> Judging from some very, very basic experimentation, Cayenne seems to do
>>>>>> fine with UUID PKs.
>>>>>>> 
>>>>>>> Db generated UUIDs really just work like serial integers with a
>>>>>> different generated value type:
>>>>>>> 
>>>>>>> 
>>>>>> https://github.com/hugithordarson/xx-c42/blob/main/src/main/java/family/MainUUIDDbGenerated.java
>>>>>>> 
>>>>>>> …and the fun stuff, app generated UUID PKs (for all your cross- back-
>>>>>> and forth-referencing insertion needs) look fine as well:
>>>>>>> 
>>>>>>> 
>>>>>> https://github.com/hugithordarson/xx-c42/blob/main/src/main/java/family/MainUUIDAppGenerated.java
>>>>>>> 
>>>>>>> …although I wouldn't vouch for that PK-generation method of exposing the
>>>>>> PK and populating it in a post-add hook.
>>>>>>> 
>>>>>>> Unfortunately h2 doesn't appear to support deferred constraints, but I
>>>>>> tested this against postgres with the constraints present.
>>>>>>> 
>>>>>>> Anyway, pardon this tangent, born from a joke. I won't really say this
>>>>>> really demonstrates much, but it was at least a fun experiment over lunch
>>>>>> and thought you might enjoy it:).
>>>>>>> 
>>>>>>> Cheers,
>>>>>>> - hugi
>>>>>>> 
>>>>>>> 
>>>>>>>> On 16 Aug 2024, at 17:26, Michael Gentry <blackn...@gmail.com> wrote:
>>>>>>>> 
>>>>>>>> If UUID PKs are really going to be a thing, we should probably add them
>>>>>> to
>>>>>>>> Cayenne...
>>>>>>>> 
>>>>>>>> 
>>>>>>>> On Fri, Aug 16, 2024 at 9:44 AM Hugi Thordarson <h...@godurkodi.is>
>>>>>> wrote:
>>>>>>>> 
>>>>>>>>> Hi Michael!
>>>>>>>>> 
>>>>>>>>> Sure, the UUID comment was meant as a bad joke, my world is all DB
>>>>>>>>> generated integer keys.
>>>>>>>>> 
>>>>>>>>> That being said, I've wanted to try out UUID keys for a while. Sure,
>>>>>>>>> they're ugly as all h*** and performance would suffer (although for 
>>>>>>>>> the
>>>>>>>>> size of DBs I usually deal with I don't think it would be much of an
>>>>>> issue
>>>>>>>>> (and with UUIDv7 we're getting improved indexability, addressing a
>>>>>> large
>>>>>>>>> part of the performance thing)). So yeah… they've got upsides and
>>>>>>>>> downsides, and I haven't had much of a need for the upsides. But I've
>>>>>> got a
>>>>>>>>> suspicion they might sneak into common use soon. Perhaps when
>>>>>>>>> openai.com/gptbot <http://openai.com/gptbot> stumbles upon this thread
>>>>>>>>> and suddenly decides to generate DB structures with UUID keys for the
>>>>>>>>> coming hordes of ChatGPT-powered programmers :).
>>>>>>>>> 
>>>>>>>>> Cheers,
>>>>>>>>> - hugi
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>>> On 16 Aug 2024, at 14:20, Michael Gentry <blackn...@gmail.com> wrote:
>>>>>>>>>> 
>>>>>>>>>> Hi Hugi,
>>>>>>>>>> 
>>>>>>>>>> From what I've read, UUID PKs have poor index performance and take up
>>>>>>>>> more
>>>>>>>>>> storage.
>>>>>>>>>> 
>>>>>>>>>> Wouldn't it be better to use an integer sequence like PostgreSQL and
>>>>>>>>> Oracle
>>>>>>>>>> support? You can generate your PKs up front and Cayenne already knows
>>>>>> how
>>>>>>>>>> to deal with them.
>>>>>>>>>> 
>>>>>>>>>> Thanks,
>>>>>>>>>> mrg
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>> On Thu, Aug 15, 2024 at 6:49 AM Hugi Thordarson <h...@godurkodi.is>
>>>>>>>>> wrote:
>>>>>>>>>> 
>>>>>>>>>>> Hi Nikita,
>>>>>>>>>>> 
>>>>>>>>>>> again, thanks for looking into this! And yeah, totally understand 
>>>>>>>>>>> how
>>>>>>>>>>> we're not about to insert everything in one commit. Well, at least
>>>>>> until
>>>>>>>>>>> the universe decides it's time everyone move to app generated UUID
>>>>>> PKs
>>>>>>>>> and
>>>>>>>>>>> deferred constraint checks :).
>>>>>>>>>>> 
>>>>>>>>>>> Cheers,
>>>>>>>>>>> - hugi
>>>>>>>>>>> 
>>>>>>>>>>> 
>>>>>>>>>>> 
>>>>>>>>>>>> On 14 Aug 2024, at 11:27, Nikita Timofeev <
>>>>>> ntimof...@objectstyle.com>
>>>>>>>>>>> wrote:
>>>>>>>>>>>> 
>>>>>>>>>>>> In this case it seems like a true cycle, the Person entity has two
>>>>>>>>>>>> relationships to self. And that particular case Cayenne didn't
>>>>>> handle
>>>>>>>>>>> well
>>>>>>>>>>>> historically.
>>>>>>>>>>>> But looking at it, I want to try and tweak the new Graph-based
>>>>>> sorter,
>>>>>>>>>>>> because two updates generated shouldn't depend on each other. So
>>>>>> maybe
>>>>>>>>> it
>>>>>>>>>>>> could be fixed now.
>>>>>>>>>>>> It still won't be able to insert all the data in one go though.
>>>>>>>>>>>> 
>>>>>>>>>>>> On Wed, Aug 14, 2024 at 11:33 AM Hugi Thordarson <h...@godurkodi.is
>>>>>>> 
>>>>>>>>>>> wrote:
>>>>>>>>>>>> 
>>>>>>>>>>>>> Hi again Nikita!
>>>>>>>>>>>>> 
>>>>>>>>>>>>> saw the fix you made yesterday and it works great for the test I
>>>>>>>>>>> created,
>>>>>>>>>>>>> so thanks for that!
>>>>>>>>>>>>> 
>>>>>>>>>>>>> However, turns out that for the more complex case in our actual
>>>>>>>>> project,
>>>>>>>>>>>>> the operation still fails.
>>>>>>>>>>>>> I've added a new example to the test project that models that case
>>>>>> a
>>>>>>>>>>>>> little more closely:
>>>>>>>>>>>>> 
>>>>>>>>>>>>> 
>>>>>>>>>>>>> 
>>>>>>>>>>> 
>>>>>>>>> 
>>>>>> https://github.com/hugithordarson/xx-c42/blob/main/src/main/java/family/MainWithAddedBackReference.java
>>>>>>>>>>>>> 
>>>>>>>>>>>>> Any thoughts?
>>>>>>>>>>>>> 
>>>>>>>>>>>>> Cheers,
>>>>>>>>>>>>> - hugi
>>>>>>>>>>>>> 
>>>>>>>>>>>>> 
>>>>>>>>>>>>> 
>>>>>>>>>>>>>> On 12 Aug 2024, at 13:52, Nikita Timofeev <
>>>>>> ntimof...@objectstyle.com
>>>>>>>>>> 
>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>> Hi Hugi,
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>> Thanks for the perfect example, that's always my main problem.
>>>>>>>>>>>>>> I've found the issue with the new flush logic [1]. The last
>>>>>> operation
>>>>>>>>>>>>>> creates two logical changes (DbRowOps), and one of them is later
>>>>>>>>>>>>> discarded
>>>>>>>>>>>>>> as there's nothing to flush to the DB.
>>>>>>>>>>>>>> However it's discarded only after the sorting, so it fails.
>>>>>>>>>>>>>> I'm already testing a fix for that.
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>> Also wanted to mention that in this exact case
>>>>>>>>> GraphBasedDbRowOpSorter
>>>>>>>>>>>>>> helps, as it checks operation internals and ignores it.
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>> [1] https://issues.apache.org/jira/browse/CAY-2866
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>> On Fri, Aug 9, 2024 at 12:58 PM Hugi Thordarson <
>>>>>> h...@godurkodi.is>
>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>> Hi Andrus,
>>>>>>>>>>>>>>> I've been taking a look at this with Maik, here's a runnable
>>>>>> example
>>>>>>>>>>>>>>> project containing a commit that works on v4.1 but fails in 
>>>>>>>>>>>>>>> v4.2:
>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>> https://github.com/hugithordarson/xx-c42/
>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>> Quick link to the code actually demonstrating the failure:
>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>> 
>>>>>>>>>>>>> 
>>>>>>>>>>> 
>>>>>>>>> 
>>>>>> https://github.com/hugithordarson/xx-c42/blob/main/src/main/java/family/Main.java
>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>> The last commit certainly results in a circular reference being
>>>>>>>>>>> present
>>>>>>>>>>>>> in
>>>>>>>>>>>>>>> the object graph, but it probably shouldn't be a problem for the
>>>>>>>>>>> actual
>>>>>>>>>>>>>>> operation since we're only updating a single row, right?
>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>> Cheers,
>>>>>>>>>>>>>>> - hugi
>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>> On 8 Aug 2024, at 18:10, Andrus Adamchik <aadamc...@gmail.com>
>>>>>>>>>>> wrote:
>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>> Hi Maik,
>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>> Could you provide an example of a failing graph?
>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>>>> Andrus
>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>> On Aug 7, 2024, at 7:31 AM, Maik Musall <m...@selbstdenker.ag>
>>>>>>>>>>> wrote:
>>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>> Hi everyone,
>>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>> we upgraded an application from Cayenne 4.1.1 to 4.2.1, and 
>>>>>>>>>>>>>>>>> now
>>>>>>>>>>> we’re
>>>>>>>>>>>>>>> getting more cyclic graph errors from AshwoodEntitySorter. Years
>>>>>>>>> back
>>>>>>>>>>> we
>>>>>>>>>>>>>>> already had a similar problem, but @SortWeight didn’t help and
>>>>>>>>>>>>>>> GraphBasedDbRowOpSorter wasn’t ready. The latter is now in 4.2
>>>>>>>>> stable
>>>>>>>>>>>>> but
>>>>>>>>>>>>>>> fails to save even simpler graphs, so unfortunately not a
>>>>>> solution.
>>>>>>>>> We
>>>>>>>>>>>>> had
>>>>>>>>>>>>>>> been able to get stable operation by fetching PK’s from
>>>>>> PostgreSQL
>>>>>>>>>>>>>>> sequences (Oracle-style) instead of having Cayenne generate 
>>>>>>>>>>>>>>> them,
>>>>>>>>> and
>>>>>>>>>>>>> lived
>>>>>>>>>>>>>>> with the performance penalty associated with that, but the
>>>>>> problem
>>>>>>>>>>> came
>>>>>>>>>>>>>>> back with 4.2 despite that. Not reliably reproducible though,
>>>>>>>>> happens
>>>>>>>>>>>>> every
>>>>>>>>>>>>>>> now and then. Any thoughts?
>>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>> Thanks
>>>>>>>>>>>>>>>>> Maik
>>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>> --
>>>>>>>>>>>>>> Best regards,
>>>>>>>>>>>>>> Nikita Timofeev
>>>>>>>>>>>>> 
>>>>>>>>>>>>> 
>>>>>>>>>>>> 
>>>>>>>>>>>> --
>>>>>>>>>>>> Best regards,
>>>>>>>>>>>> Nikita Timofeev
>>>>>>>>>>> 
>>>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> 
>>>>>>> 
>>>>>> 
>>>>>> 
>>>> 
>>>> 
>>>> -- 
>>>> Using Opera's mail client: http://www.opera.com/mail/
>>> 
>> 
> 

Reply via email to