Reputation: 31273
I reduced the problem to 3 entities in my model :
The Location
class:
@Entity
@Table(name = "***")
public class Location {
@ManyToOne
@JoinColumn(name = "s_id")
private Station s;
@ManyToOne
@JoinColumn(name = "g_id")
private GroupOfLocations group;
}
And the class for GroupOfLocation
:
@Entity
@Table(name = "***")
public class GroupOfLocation {
@ManyToOne(fetch = FetchType.LAZY) //I do not want the Station to be loaded
@JoinColumn(name = "s_id")
private Station s;
}
When I get a Location by ID:
Problem : The group contains the station but I do not want it to be loaded. I expected that fetch = FetchType.LAZY
would prevent the Station from being fully loaded but it does not work.
I have searched on SO and sometimes, the problem comes from a class declared as final
but there is no final class in this model.
Any idea?
This is how the entity id searched by ID:
public Location getById(Integer id) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Location> query = cb.createQuery(Location.class);
Root<Location> entity = query.from(Location.class);
Predicate whereClause = cb.equal(entity.get(Location_.id), id);
query.where(whereClause);
return em.createQuery(query).getSingleResult();
}
Upvotes: 4
Views: 3125
Reputation: 154090
Any JPQL or Criteria query is going to override the default fetch plan (the one you defined in the entity mapping).
The default query plan is only valid when loading the entity using find or getReference
entityManager.find(GroupOfLocation.class, 1L);
The default @ManyToOne fetch is EAGER but since you haven't issued a join fetch those will be extracted with some additional selects.
The location.group.station won't be fetched with an additional select but a Proxy will still be there.
If the location.station happens to match the location.group.station then Hibernate will use the already loaded location.station, since inside a Hibernate Session object equality matches instance equality too (meaning there can only be one object of an Entity type with a given entity identifier).
So in case both location.group.station and location.station reference the same entity, you will see an initialized Proxy, otherwise the proxy will remain uninitialized.
If the session is closed and the Proxy wasn't initialized you will get a Lazy exception when accessing it.
Upvotes: 2
Reputation: 254
But you didn't declare fetch = FetchType.LAZY on s & group property of locations.
Upvotes: 0