Why does @MapsId requires an initialized proxy object?

Well, I really try to get answers for some edge cases from the internet so that I can understand what’s going on and why, but unfortunately whether Google nor SO seem being able to help me here.

I want to understand,

  1. Why can I use an uninitialized proxy entity, which I obtained via JpaRepository#getReferenceById to set a foreign key for @ManyToOne without having to request the proxy within an upright transaction? (Only the final save will be done in a transaction.)
  2. Why can’t I go the same way when I wanna set a proxy for @MapsId? In this case I have to obtain the proxy within an upright transaction, otherwise I get an org.hibernate.PersistentObjectException: uninitialized proxy passed to persist() error.

Aren’t both actions just setting the id? In the end, Hibernate just creates native SQL and could rely on the user, that the provided proxy ids are correct. And regarding point 2, Hibernate doesn’t make an extra call to the db, so why is an initialized proxy required here and not in case 1?

Many thanks for any clarification.

You should never ever try to use a detached entity for any association. Always use a managed entity that is associated to the persistence context of the current transaction.
You might have been just lucky that Hibernate ORM didn’t throw an exception when passing a detached proxy for a regular @ManyToOne association.

Spring Data JPA is just an awful abstraction over JPA/Hibernate as it provides this “stateless” abstraction, but JPA and Hibernate ORM are stateful.
Simply put, your transaction boundary shouldn’t be at the repository, but on a higher level. You need a service layer that does transactions and coordinates multiple calls to repositories or EntityManager/Session directly within a transaction. Since if you acquire the proxy reference within that transaction, everything will work out just fine.

1 Like

Many thanks for this information, as always helps a lot.

Wish you a very nice weekend,
Cheers Slevin