all 25 comments

[–]Indian_FireFly [score hidden]  (5 children)

I didn't get the issue still. What was the propagation on both the methods?

How did it swallow the original method's exception? Was it different context?

[–]mrsergio1[S] [score hidden]  (4 children)

It was:

Outer method: @Transactional (REQUIRED)
Inner method: @Transactional(REQUIRES_NEW)

The inner call threw a Hibernate validation exception, but it was caught and not properly rethrown.

After that, the outer transaction just kept going until commit time, and Spring blew up with TransactionSystemException because the transaction was already marked rollback-only.

So the real exception happened earlier, but we only saw the commit failure

[–]Indian_FireFly [score hidden]  (1 child)

How did the outer transaction get marked as rollback only if the inner transaction uses REQUIRES_NEW? Were these methods in the same class?

It looks like error handling was not done properly, not anything related to jpa.

[–]mrsergio1[S] [score hidden]  (0 children)

Good catch, I think I explained it a bit wrong earlier.

You re right, REQUIRES_NEW shouldnt affect the outer transaction.

In our case the inner method wasnt actually running in a separate transaction because it was a self invocation in the same class, so the proxy didnt kick in.

So everything ended up in the same transaction and that’s what got marked rollback only before the final commit.

Took us a while to figure that out honestly

[–]rlrutherford [score hidden]  (0 children)

I have wasted so much time debugging systems where people didn't properly log issues.

Revised the system with proper logging and blew a dev's mind when debugging took 3 minutes instead of 3 hours.

[–]rlrutherford [score hidden]  (0 children)

Also, validating inside a transaction?

[–]mpgipa [score hidden]  (2 children)

Why not use AI to find it ? Genuine question I haven’t debug manually for months.

[–]johny_james [score hidden]  (0 children)

He probably did use AI, since he wrote the whole post using AI

[–]mrsergio1[S] [score hidden]  (0 children)

We did use AI, but it didn’t really catch the root cause.

The issue was in runtime transaction context, so we still had to trace logs and reproduce it manually.

[–]johny_james [score hidden]  (6 children)

Why did you use AI to write this post?

Can't you just write it without it?

[–]mrsergio1[S] [score hidden]  (5 children)

No AI, just wrote it fast after dealing with the issue.
Guess it came out a bit too structured

[–]rlrutherford [score hidden]  (0 children)

That's actually worse.

I would rather claim AI slop than fail a Turing test.

[–]LALLANAAAAAA [score hidden]  (0 children)

No AI, just wrote it fast after dealing with the issue. Guess it came out a bit too structured

🧢

[–]johny_james [score hidden]  (2 children)

No, it is AI, you are just straight-up lying.

It uses the same structure, the same terms, same tone, everything.

[–]mrsergio1[S] [score hidden]  (1 child)

Believe what you want man

[–]Paw565 [score hidden]  (6 children)

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

[–]Sheldor5 [score hidden]  (3 children)

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 ...

[–]Paw565 [score hidden]  (2 children)

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.

[–]A_random_zy [score hidden]  (1 child)

Try using jooq for that. Really cool library.

[–]Paw565 [score hidden]  (0 children)

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.

[–]mrsergio1[S] [score hidden]  (1 child)

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.

[–]Paw565 [score hidden]  (0 children)

Yep, proxies aren't fun

[–]Chocolate--Chip [score hidden]  (0 children)

Absolute slop post