Reputation: 508
I have a small problem with fetching eagerly in spring boot. Basically, I have an entity defined as:
@Entity
class EventEntry(
@ID
val uid
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "event_to_boxes", joinColumns = arrayOf(JoinColumn(name = "event_uid")))
@Column(name = "box_uid")
val boxUids: List<Long>
) : EventEntry(userUid, timestamp)
Now, when I am inserting data (from graphql but it's a detail), everything works fine, and I can see that on the database multiple rows are correctly persisted on the event_to_boxes table. Unfortunately, when I am retrieving all the events, something unexpected pops up.
What I see is the query asking for all the events, THEN asking once for every single list of boxUids, almost as if the FetchType.EAGER was completely ignored.
My understanding was that fetch type eager should have already got the values for the box uids when populating the event entitities. Did I miss anything or is my understanding completely wrong?
To Give a little bit more of background, I am trying to model a N-to-N relationship this way, where this is one half of the N-relationship, but I must, when getting the event entity also bring up the box uids (box is the other half of the relationship) without any additional box data
Upvotes: 0
Views: 2119
Reputation: 13041
As explained in the hibernate documentation, the FetchType.EAGER
will work only for a direct entity fetching:
EventEntry eventEntry = entityManager.find(EventEntry.class, 1L);
The
LEFT JOIN
clause is added to the generated SQL query because this association is required to be fetched eagerly.On the other hand, if you are using an entity query that does not contain a
JOIN FETCH
directive ...Hibernate uses a secondary select instead. This is because the entity query fetch policy cannot be overridden, so Hibernate requires a secondary select to ensure that the
EAGER
association is fetched prior to returning the result to the user.If you forget to
JOIN FETCH
allEAGER
associations, Hibernate is going to issue a secondary select for each and every one of those which, in turn, can lead to N+1 query issues.For this reason, you should prefer LAZY associations.
Upvotes: 3