-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Pageable sorting by join property excludes null matches [DATAJPA-252] #664
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
Comments
Oliver Drotbohm commented I fear we have to forward this to the Hibernate bug tracker as we essentially call |
Shelley J. Baker commented I've reduced the testcase to using only hibernate/jpa, but the result sets come back as expected even when setting the query's first result and max results, so the problem is not with hibernate. After a bit more debugging into spring data jpa, it looks like the problem may be that the Sort column is always prefixed with the alias of the primary entity being retrieved. In other words, when QueryUtils applies the sorting, it results in the following query:
instead of the desired query that utilizes the join alias:
Is there any way to prevent prefixing the order by column, or to perform such a query in spring-data-jpa without having to implement our own pagination support? |
Fischer Matte commented We have the same issue with spring data in our application. Whenever we sort over a ManyToOne property, rows with a null value in that column are filtered. When sorting over another column, they are included again. |
Oliver Drotbohm commented We're generating order clauses according to the JPA specification section 4.9. We could slightly change the behavior to the following without breaking too much of the JPA compatibility:
This would still not solve your special use case here as the sample you show accidentally uses and alias for the joined property that is also a property of the base entity (
Note that a usage of this advance behavior pretty much breaks the abstraction as one now has to know details of the annotated query when handing in a Do other JPA (EclipseLink, OpenJPA) providers actually suffer from the same problems? |
Oliver Drotbohm commented It turns out that the seen behavior is an implication of the JPA spec defining property expressions to always cause inner joins. I've brought this to the attention of the JPA expert group as I think this unfortunate (to phrase it politely). I'll discuss a few options regarding an improved |
Shelley J. Baker commented Thanks for the prompt responses and looking into this.
This would provide us with a temporary workaround (I agree, however, that it's not ideal as you mentioned since it would break the abstraction); however, it appears that the SimpleJpaQuery/QueryUtils still does prefix the sort with the alias, even if it doesn't exist as a property of the base entity.
|
Oliver Drotbohm commented The idea I posted was a suggestion to discuss, not saying it is now implemented like this. I also though about introducing a qualifying annotation to give the user more control over how the As a workaround I recommend manually implementing the method like described in the reference documentation as it seems to be the only way to keep this implementation detail inside the repository layer. Depending on the outcome of the discussion with the team we might also decide to not change anything at all as the way the code currently behaves is not wrong per se but influenced by the way JPA defines path expressions to be applied |
Oliver Drotbohm commented This is fixed in the current snapshot, feel free to give it a spin. We now inspect the manually defined query for aliases used in |
Shelley J. Baker commented Thanks for resolving this so quickly. I took the snapshot for a spin and it works like a charm. For reference to anyone else running into this problem in the meantime, to workaround this issue, I just added some methods to the repository that explicitly define the "order by" in the query for the problem properties. In the service from where we invoke the repository method, I just check to see if the requested order is one of the problem properties and call the alternate repository method with a copy of the pageable.
This isn't a robust solution but was a simple and feasible workaround in my case because we currently only need to support this type of sorting for one specific use case at this time. Also, the repository and code is internal so there isn't currently a need for us to be any more robust. This might not work for everyone running into this problem but was a reasonable workaround for our use case, which we'll use until spring-data-jpa 1.2 is released with this fix |
P. J. Reed commented I've found a case in which this is still not fixed. If you have a repository that extends JpaSpecficationExecutor and use the findAll method with a Specification, the resulting query still excludes null matches. I've updated the original reporter's test case to test this against the latest version and verify that it's broken. I'll attach it momentarily... |
P. J. Reed commented Test case that shows this bug still exists in version 1.2 for repositories that extend JpaSpecificationExecutor |
Oliver Drotbohm commented Is there a chance you open a new ticket for this? This ticket here is about using JPQL defined queries, not about specifications. The fix for this ticket has exactly fixed that. Especially as this fix has already been shipped I don't want to keep the ticket open for a different aspect of the problem |
P. J. Reed commented Done; see DATAJPA-277 |
Shelley J. Baker opened DATAJPA-252 and commented
When using the PagingAndSortingRepository with a Pageable query, attempts to sort by the join property will exclude entities where the join condition is absent.
From JSR-317 4.4.5.2:
According to standard SQL and JPA specs, the left outer join should always contain all entities from the "left" table even if the join condition is absent. Therefore, the exclusion of the "left" entities when there is no matching value in the "right" table seems incorrect.
For example, given an entity "Person" with optional OneToOne relationship "Address" (where Address is the owner), any attempts to retrieve pages of Person entities from the repository that are ordered by an Address property will only return Person entities that have non-null Addresses. This is only a problem for Pageable and Sort queries; using the same
@Query
with a non-pageable/sort works as expected.The resulting core sql statements (simplified slightly for brevity) are as follows; notice the additional FROM clause incorrectly added to the pageable query:
A full test case is attached. This has been tested with spring-data-jpa-1.1.1.RELEASE and hibernate-4.1.5.SP1
Affects: 1.1.2, 1.2 RC1
Attachments:
2 votes, 4 watchers
The text was updated successfully, but these errors were encountered: