Thanks for asking! I don't want to bellyache - I get paid to do this stuff,
so these are not terrible problems. But users should expect this upgrade to
require some real investment from them - it's not a drop-in at all,
especially due to the DataSource/Node changes which will hit everyone. A
lot of the rest depends on how deeply you customize the stack. Since you
asked I'll list the things I encountered. I'm not saying these are bad
changes, just that this is certainly a major release. I can imagine some
users beginning to upgrade and then stopping because of all the problems.
It's not a slam-dunk. I'm basically the sole maintainer of 7 different
server applications that all use a single shared version of cayenne, so
when I upgrade I have to upgrade them all.

Things moved to different packages - IDE can find all these if the package
was the only change; but often the class name changed too.
Replacing ServerRuntime with CayenneRuntime - not hard, but of little value
to users
Replace BaseContext with DataContext - not hard, but of little value to
users
Rename ServerRuntime.builder to CayenneRuntime.of - not hard, but of little
value to users
Renaming of all AST* classes (not automatic) - The new names are definitely
better, but this was annoying for little value returned
Replace PersistentObjectList with ToManyList - not hard, but of little
value to users

Entity object hierarchy - replace BaseDataObject with PersistentObject,
etc. Changes break Jackson JSON mixins due to new hierarchy.
My custom DataDomain subclass wasn't important enough to keep due to API
changes (not automatic)
API changes to DefaultSelectTranslator (not automatic)
Custom ObjectContext subclass was difficult to install now - there are not
great extension points for this use case. I had to modify the cayenne
source to make this easier to extend without a ton of duplication.
Custom JdbcAdapter - changes to Constant names in the constructor (not
automatic), API changes like using NativeColumnType.
Removal of DbAdapterFactory requires new way to install custom DbAdapter
and PkGenerator
Removal of DataNode and DataSourceFactory changes the way a DB connection
is established - lots of work needed to runtime creation and
binding/injection - removed extension points. Since the data source was set
up using properties (strings) and it was harder to verify everything was
correct. I've not been a fan of the binding/injection because it isn't
discoverable. As a user I have seemingly no way of knowing what extension
points are available and how to use them. The pro-tip is to read the source
for CoreModule.java but that's not a great answer, and I don't know if that
is even exhaustive.
Removal of thread bound runtime without a built-in replacement. This is
probably the hardest to address for users. I ended up just re-introducing
the same concept almost exactly. In Java 25, this can be better with
ScopedValue, but sadly I'm not on 25 yet. Thread-bound object context
remains, but is deprecated - I'll wait and do that one later I guess.

The silver lining is that LLMs help a lot with this. You can provide them
with the cayenne source code to refer to and they can rock a lot of this
stuff. And the carrot/prize is that you get much improved performance! I'm
still +1.



On Mon, Nov 2, 2026 at 4:28 PM Andrus Adamchik <[email protected]> wrote:

>
> > On Nov 2, 2026, at 3:32 PM, John Huss <[email protected]> wrote:
> >
> > I will say that upgrading to this release requires a LOT of effort. There
> > are SO many breaking changes. I get that this is a major version update,
> > and I am totally thrilled with the performance improvements. But golly,
> > this is a huge effort. It is very fortunate that we have LLMs now to help
> > with the transition, but this is still a rough process. I hope the amount
> > of breaking changes is going to slow down.
>
> Hi John,
>
> Thanks for sharing your experience. This is important, as soon others will
> start upgrading. Before I go on a rant, a question :) Can you describe your
> upgrade experience? What you needed to change and what was the hardest to
> deal with? What else can we add to UPGRADE.md to make things easier?
>
>
> Now my thoughts on the rate of change... Years ago we've noticed how
> adding even a smallest new feature is insanely hard due to how many edge
> cases needed to be handled. This is why we still don't have horizontal
> inheritance. The amount of tech debt that accumulated over two decades is
> staggering. So the product stagnated and got confusing. Just some examples:
>
> 1. Depending on how you count, there are between 15 and 23 Query
> subclasses in 4.2! How do you explain this to users? And how do you support
> all of those runtime paths?
> 2. User-facing APIs from different moments in history (DataContext has
> older methods that are not in ObjectContext; query methods are different
> between fluent queries and the context)
> 3. Three different event models (callbacks, snapshot events, filters)
> 4. Four independent cache subsystems
>
> LLMs presented a unique chance to finally get unstuck, drive towards a
> consistent mental model that can be communicated to users and meaningfully
> improve the product. But it did (does) require what essentially amounts to
> an ongoing open-heart surgery that we never dared to do before.
>
> I understand that 90% of our users have extensive existing code bases, so
> we are creating extra pain. While the core behavior is unchanged (I am
> trying to keep all the faulting contracts and such) and the model upgrade
> is done automatically, there are dozens of API changes across the board.
> More so if people built extensions based on (formally public, but outside
> ObjectContext / Query) APIs. Those things will be broken and will need to
> be redesigned as they cannot be preserved in a meaningful way.
>
> So I am constantly asking myself if we got carried away too much and when
> we should stop. From what I see now, at least 6.0 is going to be another
> breaking release (BTW it is down to just 4 essential Queries already :)).
> Hopefully we deal with all mapping and Query restructuring there and later
> work on things like caches quietly without user disruption.
>
> Andrus
>
>
>
>
>
>

Reply via email to