How Spring-JPA sucks big time

Ok, so all I am trying to do is save a new Entity into the DB and then retrieving it using its ID.

Saving my Entity

The entity Book contains an Author, some Chapters and some Genres as shown below:

While saving, the assumption is that the Author and the Genres are already present in the DB. While saving a new Book, I pass all the attributes of the Book and the Chapters. However, since the Author and the Genres are already present in the DB, I am passing their IDs only and not all of their attributes; pretty much like a Foreign Key. I am illustrating this with the below JSON:

Note that for author and genres, we are only passing their IDs and no other attributes.

Fetching the Entity I just now saved

Now, after saving the new Book, when I fetch, my expectation is that Spring-JPA fetches the entire object graph faithfully, without missing any attributes. In reality, it never even bothers to hit the DB with a query, but returns the Book from the Session Cache itself. So, when I fetch my newly saved Book, only the IDs are fetched for Author and Genre, and no other attribute.

Implementation details with Spring JPA

Repository Layer

The interface BookDao defines the contract.

The implementation looks like:

Service Layer

Note that the Transactions are started in the Repository layer. So, when I do a saveOrUpdate() in my service, there are 2 transactions that are happening. However, despite that, the Book is returned from the Session Cache and I get an incomplete object graph. Spring JPA does not give me much leverage to clear or evict or refresh the Session Cache after the insert happens.

Implementing with standard JPA

This can be handled better with the plain vanilla JPA. This is how the Repository looks like:

The below line is particularly important in the method getBook(Long bookId):


Without the above line, we will still get an incomplete object graph.


An working example of this can be found here:

Leave a Reply

Your email address will not be published. Required fields are marked *