Skip to content
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

Clarify the semantics of Fetch Joins #327

Closed
schauder opened this issue Jul 19, 2021 · 5 comments
Closed

Clarify the semantics of Fetch Joins #327

schauder opened this issue Jul 19, 2021 · 5 comments

Comments

@schauder
Copy link

I created a sample to experiment with the behaviour of Fetch Joins vs normal Joins in JPQL and Criteria API.
The experiment uses Hibernate as the most popular JPA implementation.

I found the following facts regarding Fetch Join which IMHO sometimes seem to contradict the specification if not in words then in spirit.

A clarification on the Specification both on this issue and in the actual specification would be highly appreciated.

  • Turning a Join into a Fetch Join might multiply the number of parent entities by their number of children. This seems to actually be covered by the specification:

    A fetch join has the same join semantics as the corresponding inner or outer join, except that the related objects specified on the right-hand side of the join operation are not returned in the query result or otherwise referenced in the query. Hence, for example, if department 1 has five employees, the above query returns five references to the department 1 entity.
    Section 4.4.5.3 of the JPA Specification

  • getSingleResult succeeds if a single entity is returned multiple times due to a Fetch Join. This seems to be in violation of the Specification which in the JavaDoc of getSingleResult says:

    @throws NonUniqueResultException if more than one result

  • A fetch join might implicitely be referenced by a path expression in the WHERE-clause in JPQL, but not in the Criteria API.
    If done so, the number of children returned is limited by the condition. The behaviour is undefined by the Specification but the possibility to do so seems in contradiction to the specification which explicitely mentions

    It is not permitted to specify an identification variable for the objects referenced by the right side of the FETCH JOIN clause, and hence references to the implicitly fetched entities or elements cannot appear elsewhere in the query.

  • A fetch join actually can be reused in the Criteria API by Hibernate once one realises that a Fetch implementation of Hibernate may be cast to a Join and then used as such.

All the tests are in the single test class:
https://github.com/schauder/jpa-hibernate-fetch-join-examples/blob/main/src/test/java/org/hibernate/bugs/JPAUnitTestCase.java

@gavinking
Copy link
Contributor

This issue report fails to state a problem with the JPA specification, propose a solution, or even make much sense. It seems that the reporter has some (unclear) objections to a couple of finer points of how Hibernate implements the specification, but this is definitely not the forum for such discussions. Hibernate has its own forums, mailing lists, Zulip channels, and issue tracker.

I'm going to close this.

@schauder
Copy link
Author

The problem with the JPA specification is that for the points mentioned it seems to allow behaviour that seem inconsistent.
If this is intended it should be clarified in the specification so that users know to be on the look out.
It his is not intended, the intended behaviour should be clarified, so implementation can adhere to it.

Let me know if there is more need for clarification.

@gavinking
Copy link
Contributor

it seems to allow behaviour that seem inconsistent.

"Seems" to who? It seems quite well-defined to me, and you have not explained where there is a contradiction.

@gavinking gavinking closed this as not planned Won't fix, can't repro, duplicate, stale Aug 10, 2023
@gavinking
Copy link
Contributor

I mean, as far as I understand it, your beef is with the fact that Hibernate sometimes lets you do things that the spec doesn't require that providers support.

For example, Hibernate lets you assign an alias to a fetch joined entity. Now, that's not a great feature, and I don't love it at all. And it's clearly not something that the JPA spec requires. But we allow it for legacy reasons.

And that's OK.

Implementations of JPA are allowed to have features which JPA doesn't require. And, indeed, every implementation of JPA has many such features. If you don't want to use them, don't. If you think Hibernate should not have a feature, then Hibernate has an issue tracker.

But it's certainly not the role of the JPA spec to prohibit implementations from having additional features that aren't in the spec! The role of the spec is to define what is portable between implementations.

@schauder
Copy link
Author

"Seems" to who?

To me, of course. And I'm inclined since the question has two upvotes to others as well.

you have not explained where there is a contradiction

  1. If one uses a FETCH JOIN on a one to many relationship multiple references to the same entity are returned. But although getSingleResult is supposed to throw an exception when multiple results are returned it does not throw an exception in such a case.

  2. A fetch join might implicitly be referenced by a path expression in the WHERE-clause in JPQL, although the specification says this is illegal.

Of course, if the JPA team decides that these are actual violations of the specification I'm happy to take the to the Hibernate team.
But either way I'd like to see some clarifications in the specification for both cases if this behaviour is

a) the intended behaviour

b) in violation of the specification

c) acceptable implementation dependent behaviour

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants