15.18. Special case - qualified path expressions
<div class="paragraph">
We said earlier that collection-valued associations actually refer to the _values_ of that collection.
Based on the type of collection, there are also available a set of explicit qualification expressions.
</div>
<div id="hql-collection-qualification-example" class="exampleblock">
<div class="title">Example 380. Qualified collection references example</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight">`@OneToMany(mappedBy = "phone")
@MapKey(name = "timestamp")
@MapKeyTemporal(TemporalType.TIMESTAMP )
private Map<Date, Call> callHistory = new HashMap<>();
// select all the calls (the map value) for a given Phone
List<Call> calls = entityManager.createQuery(
"select ch " +
"from Phone ph " +
"join ph.callHistory ch " +
"where ph.id = :id ", Call.class )
.setParameter( "id", id )
.getResultList();
// same as above
List<Call> calls = entityManager.createQuery(
"select value(ch) " +
"from Phone ph " +
"join ph.callHistory ch " +
"where ph.id = :id ", Call.class )
.setParameter( "id", id )
.getResultList();
// select all the Call timestamps (the map key) for a given Phone
List<Date> timestamps = entityManager.createQuery(
"select key(ch) " +
"from Phone ph " +
"join ph.callHistory ch " +
"where ph.id = :id ", Date.class )
.setParameter( "id", id )
.getResultList();
// select all the Call and their timestamps (the 'Map.Entry') for a given Phone
List<Map.Entry<Date, Call>> callHistory = entityManager.createQuery(
"select entry(ch) " +
"from Phone ph " +
"join ph.callHistory ch " +
"where ph.id = :id " )
.setParameter( "id", id )
.getResultList();
// Sum all call durations for a given Phone of a specific Person
Long duration = entityManager.createQuery(
"select sum(ch.duration) " +
"from Person pr " +
"join pr.phones ph " +
"join ph.callHistory ch " +
"where ph.id = :id " +
" and index(ph) = :phoneIndex", Long.class )
.setParameter( "id", id )
.setParameter( "phoneIndex", phoneIndex )
.getSingleResult();`</pre>
</div>
</div>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">VALUE</dt>
<dd>
Refers to the collection value.
Same as not specifying a qualifier.
Useful to explicitly show intent.
Valid for any type of collection-valued reference.
</dd>
<dt class="hdlist1">INDEX</dt>
<dd>
According to HQL rules, this is valid for both `Maps` and `Lists` which specify a `javax.persistence.OrderColumn` annotation to refer to the `Map` key or the `List` position (aka the `OrderColumn` value).
JPQL however, reserves this for use in the `List` case and adds `KEY` for the `Map` case.
Applications interested in JPA provider portability should be aware of this distinction.
</dd>
<dt class="hdlist1">KEY</dt>
<dd>
Valid only for `Maps`. Refers to the map’s key. If the key is itself an entity, it can be further navigated.
</dd>
<dt class="hdlist1">ENTRY</dt>
<dd>
Only valid for `Maps`. Refers to the map’s logical `java.util.Map.Entry` tuple (the combination of its key and value).
`ENTRY` is only valid as a terminal path and it’s applicable to the `SELECT` clause only.
</dd>
</dl>
</div>
<div class="paragraph">
See [Collection-related expressions](#hql-collection-expressions) for additional details on collection related expressions.
</div>
</div>
<div class="sect2">