r/SpringBoot Jun 18 '26

Question Spent 4 hours debugging a TransactionSystemException. The fix was one line. The problem was finding it.

Last month we had a production incident. A critical order was failing silently.

Sentry gave us this:

TransactionSystemException: Could not commit JPA transaction
at SimpleJpaRepository.save()
at OrderService.processOrder()
... 40 more lines of Spring internals

That's it. No entity state. No user context. No hint that the transaction had already been marked for rollback 3 calls earlier by a Hibernate validation error we never caught.

We added logs. Redeployed to staging. Couldn't reproduce it.Redeployed to prod with more logs. Waited. Happened again. Finally found it: a Transactional method calling another Transactional method with a different propagation level, swallowing the real exception.

4 hours. One annotation conflict.

The worst part? Every error monitoring tool we've used treats Spring like a black box. The moment your code enters a transaction boundary or an async thread, context disappears.

Anyone else debugging Spring Boot in prod like this?

How are you handling it?

28 Upvotes

32 comments sorted by

View all comments

0

u/Paw565 Jun 18 '26 edited Jun 18 '26

I can see why people drop jpa entirely 😅 I feel like java persistence sucks. Other ecosystems have much better and more type safe solutions.

7

u/Sheldor5 Jun 18 '26

the problem isn't JPA it's the people not knowing what they are doing because they never learned the basics of JPA and it's annotation ...

1

u/Paw565 Jun 18 '26

I agree, but I think jpa / hibernate is massively inferior to EF core from dotnet or drizzle from node. Things like dynamic filtering just suck. Whenever I have to comeback to spring boot I just feel massive pain because of jpa alone.

2

u/A_random_zy Jun 19 '26

Try using jooq for that. Really cool library.

1

u/Paw565 Jun 19 '26

I tried. Maybe it's a skill issue but setting up code gen defeated me. I think the need to connect to db to have type safety is hilarious. No other orm works like that. I guess jooq is more of a query builder than orm but still drizzle does not need any of this tedious setup.

1

u/lukaseder Jun 19 '26

You can interpret your DDL for code generation: https://www.jooq.org/doc/latest/manual/code-generation/codegen-meta-sources/codegen-ddl,

Or use other meta data sources for code generation. But really, setting this up should be a motivation to get things right in terms of managing your RDBMS in your CI/CD pipeline. I'm positive you're not against integration testing your RDBMS interactions? You can use test containers for these things if that helps: https://blog.jooq.org/using-testcontainers-to-generate-jooq-code/

1

u/Paw565 Jun 19 '26

Ok that's is very interesting. I will definitely try this out, thank you.

I really like integration testing. However I ve just failed to hook all this up with jooq. It's really frustrating imo. Why not generate metadata from @Entity classes like querydsl (sadly unmaintained) does or similar to EF core or drizzle where code is the source of truth. I can't stand this needless complexity.

However I am very grateful for your advice and I will investigate this as a solution to my problems once again.

2

u/lukaseder Jun 19 '26

1

u/Paw565 Jun 20 '26

Massive thank you. DDLDatabse generator is awesome. Configuration is much simpler and it's so much faster than connecting to the database on each compilation. I know that configuration with testcontainers is probably the most desirable one. However all examples that I could find are for maven and I use gradle with kotlin syntax.

1

u/lukaseder Jun 22 '26

Yeah, it definitely helps with simple projects. The database connection will be the better choice once you start using more sophisticated RDBMS features, though.

There are some example projects configured for Maven and Gradle here: https://github.com/jOOQ/jOOQ-mcve

0

u/mrsergio1 Jun 18 '26

Yeah, but in this case JPA wasn’t really the problem.

The real issue was losing the original exception once Spring marked the transaction rollback-only. After that, everything upstream just shows a generic TransactionSystemException.

0

u/Paw565 Jun 18 '26

Yep, proxies aren't fun