[hibernate-dev] Extended KEY expression support
Christian Beikov
christian.beikov at gmail.com
Fri Jan 27 14:25:12 EST 2017
I have a little proposal for supporting the use of a KEY expression in
the FROM clause and I'd like to hear your opinions on that.
Unfortunately the JPA spec does not support that, but since a key of a
java.util.Map mapping may be an entity type, we need to specify how one
can "join" that key explicitly.
Right now(pre HHH-10537), when joining a java.util.Map mapping, an inner
join is generated for the map key entity type. In my fix for HHH-10537 I
changed the behavior to respect/inherit the join type of the collection
join.
The problem is, that one can't further join any attributes on that key,
because there is no syntax in the HQL or the JPA spec that allows to do
that.
We need to decide (1) whether we always want to join the entity key or
require the user to do that specifically via e.g. something like "JOIN
alias.map m JOIN KEY(m) k"
and also (2) how the syntax for joining further attributes should look
like. If we decide to not allow the "JOIN KEY(m)" syntax for (1) we have
to support something like "JOIN KEY(m).association", otherwise we can
just use the alias like for normal joins "JOIN k.association".
Either way, we have to change the grammar but I'd rather like to
support/implement the map key joining syntax like "JOIN KEY(m) k" for
(1). A further change to that would be to not generate the implicit key
table join anymore but require the user to do the join explicitly. Since
that would break backwards compatibility, I'd like to make that behavior
configurable and of course, by default it will generate the implicit key
join to maintain backwards compatibility. I also propose to switch the
default in 6.0 so that the join is not generate anymore.
The usage in the JPA Criteria API will unfortunately require a cast
since the return type of javax.persistence.metamodel.MapAttribute#key()
is javax.persistence.metamodel.Path instead of
javax.persistence.metamodel.SingularAttribute but essentially the same
functionality is available to a user out of the box.
Specifying a custom join for a key would look like this in the Criteria API
MapAttribute<Entity, MapKeyEntity, MapValueEntity> mapAttribute = ...
Join<Entity, MapKeyEntity> keyEntity =
mapAttribute.join((SingularAttribute<? super Entity, ? extends
MapKeyEntity>) mapAttribute.key(), JoinType.LEFT);
keyEntity.join(...)
So the questions again.
1. Do you all agree that this is important and should be done?
2. Agree to not generate implicit joins for keys in future versions?
3. Allow joining the key in a separate join?
4. Allow further joins on a key?
5. Happy with how it can be done in JPA Criteria?
In addition to that, it would be nice if anyone could make someone from
the JPA EG aware of this.
From a JPQL BNF point of view, I'd propose the following changes
from
join_single_valued_path_expression::=
identification_variable.{single_valued_embeddable_object_field.}*single_valued_object_field
to
join_single_valued_path_expression::=
identification_variable.{single_valued_embeddable_object_field.}*single_valued_object_field
|
map_field_identification_variable
Regards,
Christian
More information about the hibernate-dev
mailing list