Re: UUIDs
"Jurgen Doll" <[email protected]> Tue, 27 Aug 2024 09:53:42 +0200
| Newsgroups | gmane.comp.java.cayenne.user |
|---|---|
| Organization | iVory EMR |
| Message-ID | <op.2s5j7szzy9kazd@admin-pc> |
Talking of holes .... in my code I've found that if a DbEntity's BINARY UUID PK is either not exposed or is exposed as a byte[] in the ObjEntity then all is well. But if the BINARY UUID is materialized in the ObjEntity as a UUID object then there are problems with cache lookups, if I remember correctly. So I had to modify ObjectIdSingle constructor to convert the UUID value to a byte[] for consistent comparisons. Which meant that I had modify DataRowUtils.refreshObjectWithSnapshot.visitAttribute to convert the byte[] back to a UUID if the ObjAttribute required it. And the same for ReplacementIdVisitor.updateId for meaningful PKs. Just reporting my experience, maybe I did it all wrong :-) Regards Jurgen On Mon, 26 Aug 2024 21:05:23 +0200, Andrus Adamchik <[email protected]> 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 <[email protected]> >> 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 <[email protected]> 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 >>> <[email protected]> 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 <[email protected]> >>>> 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 <[email protected]> >>>>>> 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 <[email protected]> >>>>>>> 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 <[email protected]> >>>>> 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 <[email protected]> >>>>>>>>> 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 >>>>>>>>> <[email protected]> >>>>>>>> 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 < >>>>> [email protected]> >>>>>>>>>> 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 >>>>>>>>>>> <[email protected] >>>>>> >>>>>>>>>> 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 < >>>>> [email protected] >>>>>>>>> >>>>>>>>>>>> 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 < >>>>> [email protected]> >>>>>>>>>>>> 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 >>>>>>>>>>>>>>> <[email protected]> >>>>>>>>>> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hi Maik, >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Could you provide an example of a failing graph? >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Thanks, >>>>>>>>>>>>>>> Andrus >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Aug 7, 2024, at 7:31 AM, Maik Musall >>>>>>>>>>>>>>>> <[email protected]> >>>>>>>>>> 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/ >> > -- Using Opera's mail client: http://www.opera.com/mail/