Skip to content

Entity return type marked as projection #3308

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

Closed
Bethibande opened this issue Jun 10, 2025 · 2 comments
Closed

Entity return type marked as projection #3308

Bethibande opened this issue Jun 10, 2025 · 2 comments
Labels
status: waiting-for-feedback We need additional information before we can continue status: waiting-for-triage An issue we've not yet triaged

Comments

@Bethibande
Copy link

Due to spring-projects/spring-data-jpa#3076 we've noticed a bug occurring in an old repository class of ours.
The setup is as follows:

@Entity
public class EntityA {
    // some fields, getters and setters...
}

@Entity
public class EntityB {
    // some fields, getters and setters...
}

@Repository
public interface RepositoryA extends JpaRepository<EntityA, Long> {

    @Query("SELECT b FROM EntityB b where b.field = :field")
    List<EntityB> getEntityBBySomeField(final @Param("field") String field)
}

This is the result of some legacy code, and likely someone being too lazy to create a separate repository class for just one method.
The QueryMethod object for this repository method now returns the class EntityA instead of EntityB when calling its getDomainClass method. The logic used to determine the correct domain class seems to always prioritize the repository type over the method domain type.

this.domainClass = Lazy.of(() -> {

Class<?> repositoryDomainClass = metadata.getDomainType();
Class<?> methodDomainClass = metadata.getReturnedDomainClass(method);

return repositoryDomainClass == null || repositoryDomainClass.isAssignableFrom(methodDomainClass)
		? methodDomainClass
		: repositoryDomainClass;
});

This then causes the ReturnedType object for the method to mark the return type as a projection since the return type doesn't match the domain type, which then triggers the query rewrite from the issue above.
All that then results in a runtime exception since the generated constructor query is incorrect as our EntityB class doesn't have a constructor and the query validation fails with an obscure syntax error.
For now I'll fix this by just moving the method in question to a new repository, but it still feels like this should work, and it has worked for a long time without any issues.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jun 10, 2025
@mp911de
Copy link
Member

mp911de commented Jun 10, 2025

Thanks for reaching out and looking into the code. This is a known issue that was unintentionally introduced. It has been fixed via spring-projects/spring-data-jpa#3895 in the 3.5.1 snapshot builds.

Technically, the returned type is considered correctly a projection. With DTO query rewriting, we only introspect selection items but not their origin to verify what type is being returned. Therefore the fix checks whether the returned type is JPA-managed. If so, we refrain from rewriting the query.

Please check out the latest snapshots whether they bring back the previous behavior for you.

@mp911de mp911de added the status: waiting-for-feedback We need additional information before we can continue label Jun 10, 2025
@Bethibande
Copy link
Author

Yes, that seems to have fixed it. Thanks for your quick reply. And it's quite interesting I didn't know this was considered a projection too, I learned something new today, even if it doesn't seem to make any notable difference.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: waiting-for-feedback We need additional information before we can continue status: waiting-for-triage An issue we've not yet triaged
Projects
None yet
Development

No branches or pull requests

3 participants