Hi Samuel, Yeah, Expressions (the things actually generated by the Properties) can be used for both querying the DB and for in-memory evaluation, i.e. what you call "object queries”. I haven’t looked much into how much you can do “in-memory” with the more complex Expressions though, have to do some experimentation on that.
I’d like to say “yes” regarding using some of that Property magic on generic objects/methods rather than Persistent object attributes, I certainly have in the past. But Cayenne is focused on using this for Persistent objects and their modeled attributes so there might be caveats I don’t know of currently. I have replaced most of the code where I used Cayenne to perform actions on generic objects/methods with Streams, but I know what you mean — ERXKey/Property is certainly nicer in some ways, especially when it comes to working with nested objects (long keypaths). Feel free to hit me up here or in #cayenne on Slack if you decide to check out Cayenne and need some rubber ducking. I incidentally made a video last night for another WO guy on creating a simple WO/Cayenne project from scratch. It auto-generates an in-memory h2 database at application startup from the model, meaning you can play around with adding things to the model and try out features along the way. Video: https://www.youtube.com/watch?v=Ahu3Qnki1-w Project: https://github.com/hugithordarson/cay Cheers, - hugi PS: The example query in the previous message was kind of nonsensical (sum on receipt total? wat?) and I even pasted in the wrong SQL (generated by a previous version of the example query). Pardon that, I’ll probably write a short article and then include some actual, correct examples :) > On 3 Feb 2025, at 13:56, Samuel Pelletier <sam...@samkar.com> wrote: > > Hi Hugi, > > So those Properties can build objects queries AND more custom queries like > ERXQuery, seems very cool. > > Can you create Properties for EO methods ? I have many of them for things > like "return a previously set value or compute a default one"... > > I want to play with Cayenne but have not found the real good yet... Porting a > large application seems a bit too big to experiment a new frameworks but I > have a personal project that seems a very good fit. > > Regards, > > Samuel > > >> Le 3 févr. 2025 à 08:12, Hugi Thordarson via Webobjects-dev >> <webobjects-dev@lists.apple.com> a écrit : >> >> Hi Samuel, >> >> Yes, we have a very nice querying API/syntax similar to ERXKey in Cayenne >> (although they’re called “Properties” in the Cayenne world). >> >> For example, selecting all my receipts, ordering them by date and >> prefetching their entries: >> >> ==== >> ObjectSelect >> .query( Receipt.class ) >> .where( Receipt.USER.dot( User.NAME ).eq( “Hugi Þórðarson” ) ) >> .orderBy( Receipt.SHOP ).dot( Shop.NAME ).desc() ) >> .prefetch( Receipt.ENTRIES.joint(); >> .select( objectContext ); >> ==== >> >> They’ve also evolved quite a bit in the last years along with Cayenne’s >> SQL/querying abilities and now include fun stuff like SQL subqueries, >> aggregates, functions and features like EXISTS and HAVING. So for a more >> complex example, selecting a [Receipt]’s date/total, the related [Shop]’s >> name, the number of it’s related [Entry] records, with a creation_date in >> year 2023, where they have more than five entries, a higher total than 1.000 >> and have a related OcrResult object (nonsensical query, but yeah… it’s a >> demo): >> >> ==== >> ObjectSelect >> .query( Receipt.class ) >> .columns( >> Receipt.DATE_ONLY, >> Receipt.TOTAL_AS_WRITTEN_ON_RECEIPT, >> Receipt.SHOP.dot( Shop.NAME ), >> Receipt.ENTRIES.count() >> ) >> .where( >> Receipt.USER.dot( User.NAME ).in( "Hugi Þórðarson", "Ósk Gunnlaugsdóttir" ) >> .andExp( Receipt.CREATION_DATE.year().eq( 2023 ) ) >> .andExp( Receipt.OCR_RESULTS.exists() ) >> ) >> .having( >> Receipt.ENTRIES.count().gt( 5l ) >> .andExp( Receipt.TOTAL_AS_WRITTEN_ON_RECEIPT.sum().gt( BigDecimal.valueOf( >> 1000 ) ) ) >> ) >> .orderBy( >> Receipt.ENTRIES.count().desc() >> ) >> .select( oc ); >> ==== >> >> … generating the following SQL: >> >> ==== >> SELECT "t0"."date_only", "t1"."name", COUNT( "t2"."id" ), >> "t0"."total_as_written_on_receipt" FROM "fd_receipt" "t0" JOIN "fd_shop" >> "t1" ON "t0"."shop_id" = "t1"."id" JOIN "fd_entry" "t2" ON "t0"."id" = >> "t2"."receipt_id" JOIN "fd_user" "t3" ON "t0"."user_id" = "t3"."id" WHERE ( >> "t3"."name" = ? ) AND ( EXTRACT(YEAR FROM "t0"."creation_date") = ? ) AND >> EXISTS (SELECT "t4"."id" FROM "fd_ocr_result" "t4" WHERE "t4"."receipt_id" = >> "t0"."id") GROUP BY "t0"."date_only", "t1"."name", >> "t0"."total_as_written_on_receipt" HAVING ( ( COUNT( "t2"."id" ) > ? ) AND ( >> SUM( "t0"."total_as_written_on_receipt" ) > ? ) ) ORDER BY COUNT( "t2"."id" >> ) DESC [bind: 1->name:'Hugi Þórðarson', 2:2023, 3:5, 4:1000] >> ==== >> >> This showcases just a part of the features, and works so well it feels >> almost magical at times. I could also have specified Receipt.SELF as a >> “column” instead of fetching specific values of the Receipt entity, meaning >> I get the entire Receipt object (with all it's associated ORM features) >> along with it’s aggregate values. I use this quite a lot (didn’t do that in >> the example since it makes the resulting SQL longer, since there’s a lot of >> columns involved). >> >> And yes, you can use Properties to perform in-memory operations like >> filtering and sorting. >> >> Receipt.CREATION_DATE.desc().orderedList( receipt ); >> Receipt.USER.dot( User.NAME ).eq( “Hugi” ).filterObjects ( receipts ); >> >> Cheers, >> - hugi >> >> >> >>> On 3 Feb 2025, at 12:18, Samuel Pelletier via Webobjects-dev >>> <webobjects-dev@lists.apple.com> wrote: >>> >>> HI, >>> >>> Those NS collections where essentials in the first java WO mainly because >>> at that time Java did not had real collections classes (they appeared in >>> Java 1.8), and the name was probably kept to help porting. I did not switch >>> to java WO at that time and maintained some objective-C apps for a long >>> time! >>> >>> I mostly use the NS versions because I'm still on EOF and uses ERXKey for >>> sort orderings, qualifier building and aggregate computation to have type >>> checking: >>> >>> - EOQualifier qualifier = >>> Evenement.DATE.greaterThanOrEqualTo(dateDebut()).and(Evenement.DATE.lessThanOrEqualTo(dateFin())); >>> - ERXKey.sum(ContratRetenue.NB_HEURES).valueInObject(retenues); >>> - NSArray<Etudiant> etudiants = >>> Groupe.ETUDIANTS_ACTIFS.atFlatten().arrayValueInObject(evenement.groupes()); >>> - sortOrderings = Evenement.DATE.asc() >>> .then(Evenement.ORDRE_AFF_MOIS_SALLE.asc()) >>> >>> .then(Evenement.GROUPE_PRINCIPAL.dot(Groupe.SEMESTRE_DEBUT.dot(Semestre.DATE_DEBUT)).desc() >>> .then(Evenement.HEURE_DEBUT.asc())); >>> >>> I still think those are more readable than creating lambda, probably mostly >>> explained because I'm use to the syntax. >>> >>> Is there something like ERXKey when using Cayenne ? >>> >>> Regards, >>> >>> Samuel >>> >>> >>>> Le 2 févr. 2025 à 07:21, Amedeo Mantica via Webobjects-dev >>>> <webobjects-dev@lists.apple.com> a écrit : >>>> >>>> Iirc the NS collections were there due to simplifying porting of apps from >>>> objc to Java. I don’t think there is any big difference in performance >>>> >>>> Sent from my iPhone >>>> >>>>> On 2 Feb 2025, at 12:18, Jérémy DE ROYER via Webobjects-dev >>>>> <webobjects-dev@lists.apple.com> wrote: >>>>> >>>>> Hi all, >>>>> >>>>> Even if I still use EOF (due to inheritance limitations of Cayenne), I >>>>> followed Hugi’s precepts : >>>>> - « use 100% java native whenever possible » >>>>> >>>>> One other advantage when working in a team… is that 100% java is widely >>>>> documented and exampled... and it's more attractive to newbees. >>>>> >>>>> Sorry if I don’t « really » answer the question 😄 >>>>> >>>>> Jérémy >>>>> >>>>>> Le 2 févr. 2025 à 11:13, Hugi Thordarson via Webobjects-dev >>>>>> <webobjects-dev@lists.apple.com> a écrit : >>>>>> >>>>>> When I made the switch to Java collections I did do some benchmarking. >>>>>> Haven’t got the code anymore (this was a decade ago) but at that time, >>>>>> the Java collection classes were faster, but the operations were really >>>>>> so fast in both cases that the differences were negligible — at that >>>>>> time. >>>>>> >>>>>> Since then, a decade of improvements has happened in the Java >>>>>> collections so I think we can guess where you’ll find performance >>>>>> improvements — and will keep getting performance improvements. On one >>>>>> hand you have old classes written in an old version of Java, on the >>>>>> other hand you have actively maintained open source classes used by >>>>>> millions of programmers and maintained by the performance-obsessed >>>>>> authors of Java and the JDK itself. >>>>>> >>>>>> And now for the opinion piece: >>>>>> Unless you’re writing extremely performance-sensitive code — even if the >>>>>> foundation collections were faster I think it makes sense to use Java >>>>>> collections and write to the standard Java collection APIs where you >>>>>> don’t *need* foundation collections, because If you’re using foundation >>>>>> specific APIs, your code is really already obsolete at the time of >>>>>> writing. I never regretted the switch and have hardly seen an NS* >>>>>> collection class in my code in years, except where explicitly required >>>>>> as a parameter for passing into WO APIs. (that story may be a little >>>>>> different if you’re using EOF which uses the NS collections everywhere, >>>>>> so this may not apply in that case). >>>>>> >>>>>> The Java collection classes do have their warts, the most obvious one to >>>>>> us coming from the NS* world being the non-API-differentiation between >>>>>> mutable and immutable collections (weird design oversight) but that >>>>>> hasn't plagued me, really. It’s just something you’re aware of and don’t >>>>>> really hit often. >>>>>> >>>>>> Another one for us WO users is that you can’t use KVC operators on Java >>>>>> collections (someArray.@sortAsc, .@sum etc). When I made the switch I >>>>>> always thought I’d miss these hugely and planned to write operator >>>>>> support into ERXComponent’s valueForKeyPath(), but never got around to >>>>>> it since I really didn’t miss the operators, preferring to keep my logic >>>>>> in Java rather than templates (compile time errors and refactoring >>>>>> support are awesome things). >>>>>> >>>>>> Probably just saying things you know — but I thought it might have some >>>>>> value hearing from someone that moved to Java collections and doesn’t >>>>>> regret it. >>>>>> >>>>>> Cheers, >>>>>> - hugi >>>>>> >>>>>> >>>>>>> On 2 Feb 2025, at 00:29, ocs--- via Webobjects-dev >>>>>>> <webobjects-dev@lists.apple.com> wrote: >>>>>>> >>>>>>> Hi there, >>>>>>> >>>>>>> did ever anybody tried some benchmarks to find whether it is better to >>>>>>> use WO collections (NSArray, NSDictionary...) as widely as possible (ie >>>>>>> essentially anywhere, unless one really needs to store nulls or can't >>>>>>> do without ConcurrentHashMap or so), or whether it's better to use >>>>>>> standard collections (List, HashMap...) wherever they happen to work >>>>>>> properly (which is surprisingly often, but not anywhere)? >>>>>>> >>>>>>> Are they roughly comparable, or are one or the others considerably >>>>>>> better? >>>>>>> >>>>>>> Thanks! >>>>>>> OC >>>>>>> >>>>>>> _______________________________________________ >>>>>>> Do not post admin requests to the list. They will be ignored. >>>>>>> Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) >>>>>>> Help/Unsubscribe/Update your Subscription: >>>>>>> https://lists.apple.com/mailman/options/webobjects-dev/hugi%40karlmenn.is >>>>>>> >>>>>>> This email sent to h...@karlmenn.is >>>>>> >>>>>> _______________________________________________ >>>>>> Do not post admin requests to the list. They will be ignored. >>>>>> Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) >>>>>> Help/Unsubscribe/Update your Subscription: >>>>>> https://lists.apple.com/mailman/options/webobjects-dev/jeremy.deroyer%40ingencys.net >>>>>> >>>>>> This email sent to jeremy.dero...@ingencys.net >>>>> >>>>> _______________________________________________ >>>>> Do not post admin requests to the list. They will be ignored. >>>>> Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) >>>>> Help/Unsubscribe/Update your Subscription: >>>>> https://lists.apple.com/mailman/options/webobjects-dev/amedeomantica%40me.com >>>>> >>>>> This email sent to amedeomant...@me.com >>>> _______________________________________________ >>>> Do not post admin requests to the list. They will be ignored. >>>> Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) >>>> Help/Unsubscribe/Update your Subscription: >>>> https://lists.apple.com/mailman/options/webobjects-dev/samuel%40samkar.com >>>> >>>> This email sent to sam...@samkar.com >>> >>> _______________________________________________ >>> Do not post admin requests to the list. They will be ignored. >>> Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) >>> Help/Unsubscribe/Update your Subscription: >>> https://lists.apple.com/mailman/options/webobjects-dev/hugi%40karlmenn.is >>> >>> This email sent to h...@karlmenn.is >> >> _______________________________________________ >> Do not post admin requests to the list. They will be ignored. >> Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) >> Help/Unsubscribe/Update your Subscription: >> https://lists.apple.com/mailman/options/webobjects-dev/samuel%40samkar.com >> >> This email sent to sam...@samkar.com > _______________________________________________ Do not post admin requests to the list. They will be ignored. Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com