[hibernate-dev] Extended KEY expression support

Christian Beikov christian.beikov at gmail.com
Fri Jan 27 15:28:47 EST 2017


Fwiw EclipseLink supports both syntaxes "JOIN KEY(m) k" and also "JOIN 
KEY(m).association".

Am 27.01.2017 um 20:25 schrieb Christian Beikov:
> 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