How do I force a specific query to lazy load an attribute, that usually has eager loading? EntityGraphType.FETCH isn't working.
@NamedEntityGraph(name="negGraphName",attributeNodes={
@NamedAttributeNode("name"),
@NamedAttributeNode("grup")})
class User{
private String name;
@ManyToOne
private UserGroup grup;
@ManyToMany(fetch=FetchType.EAGER)
protected Set<Authority> authoritiesList;
}
interface UserRepository extends CrudRepository<String, User>{
@EntityGraph(value="negGraphName", type=EntityGraphType.FETCH)
@Query("<custom query here>")
private Collection<User> getUsersInSpecialQuery(@Param("paramName") String paramName);
}
basically, when I call userRepository.getUsersInSpecialQuery()
the initial query joins in object, and doesn't join in authority, however then Hibernate anyway initializes the authorities list with A SEPARATE SQL QUERY PER USER RESULT, which is highly inefficient. Also, it initializes DomainObject object graph parent which is not even marked as Eager.
Disabling fetch=FetchType.EAGER
on authorityList disabled the additional per-user queries, but I still want it eagerly fetched for all other queries.
EntityGraphType.Fetch
's javadoc says:
When the javax.persistence.fetchgraph property is used to specify an entity graph, attributes that are specified by attribute nodes of the entity graph are treated as FetchType.EAGER and attributes that are not specified are treated as FetchType.LAZY
however clearly this is not the case for me
Hibernate : Force lazy-loadding on eager field <-- Doesn't have a solution
Fetch Type LAZY still causes Eager loading Hibernate Spring data <-- claims the problem is that the lazy attribute was loaded by viewing, however in my case, I stepped through in hibernate, and it was during materialization of the User object
You cant make an EAGER assosciation LAZY. I suggest you make it LAZY and in all queries where you want it EAGERly JOIN FETCH the authoritiesList
so they are effectively EAGER then.
Another option is a subentity which is basically the same as your current user entity, mapped to the same DB table but without the relationship you dont want:
@Entity
@Table(name="SAME_TABLE_AS_USER_ENTITY")
class BasicUser{
private String name;
@ManyToOne
private UserGroup grup;
}
Another option would be inheritance.