New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Projections do not load ManyToOne relations lazily #2183
Comments
The idea of projections is to have exactly those columns in the projection, that you need. If you need some data only sometimes the correct approach would be to have separate projections for the different cases. |
That is theoretically all right. But in the real world I have an entity with 8 attributes (and 6 projections combining them), 3 of them are a ManyToOne relation to other entities, each with 8 attributes (and more than 5 projections each). Which means that I would need more than 625 projections just for that entity. Even if I implemented them, I would still not be able to perform optimized queries since nested projections select all the fields of its entity, not just those defined by its getters. That is why I preffer to select just the ID of the ManyToOne relation and then use it to perform another query to retrieve an specific projection of the related entity. But I cannot achieve this either since the ManyToOne relation is always fetched eagerly. In other words, in a projection with a ManyToOne relation, the related entity always gets all its columns selected (even if it is a nested projection and even if it is annotated to get lazily fetched). Which pretty much makes projections useless (except those that do not need any relation, which is not usual in the real world) since the only way not to select all the attributes of an entity implies selecting all the attributes of its ManyToOne related entities. The mechanism that JPA offers to load less columns from the database to optimize queries ends up loading more columns. |
I can see your problem. This is not what Spring Data projections are intended for and we won't add lazy loading for them. Use JPA/the |
Could you at least consider implementing nested projections in a way that they only select the columns defined in their getters (as discussed in #1555)? |
LEFT JOIN FETCH works for me. @Query(value =
"SELECT gr FROM GroupEntity gr " +
"LEFT JOIN FETCH gr.ownerAccount " +
"WHERE gr.groupId = :groupId ") |
Hello. I have an entity representing a MySQL table:
And a projection:
This is my repository:
When I retrieve the entity, the
ownerAccount
is loaded lazily (the Hibernate MySQL query only selects its ID) but when I retrieve the projection, it is loaded eagerly (the Hibernate MySQL query does an inner join with all theAccountEntity
columns). So there is no way I can retrieve only some columns of theGroupEntity
(I have to retrieve all of them using the entity, or some of them plus all the columns of theAccountEntity
using the projection).Is there a way I can get the projection to load the
@ManyToOne
relation lazily? I've tried annotating thegetOwnerAccount()
method of projection with@ManyToOne(fetch = FetchType.LAZY, optional = false)
and@LazyToOne(LazyToOneOption.PROXY)
but it did not work.EDIT:
Changing
GroupBaseProjection
so thatgetOwnerAccount()
returns a nested projection instead of an entity should solve the problem, but it does not since nested projections select all columns, not just those defined in its getters (because this feature request was rejected: #1555)Maybe using DTOs instead of projections could solve the problem, but they cannot be used either because of this bug: #2009
The text was updated successfully, but these errors were encountered: