[hibernate-dev] 6.0 - ResultTransformer

Steve Ebersole steve at hibernate.org
Tue Sep 13 19:00:33 EDT 2016


So here is the path I am following initially.. It is straightforward to
explain to a user which I like.

In terms of processing each "row" in a result there is the RowTransformer
contract I mentioned earlier, or maybe I mentioned on HipChat.  I added the
capability for RowTransformer to be nested, specifically I defined 2 levels:

   1. an implicit RowTransformer.  This is resolved based on the following
   chart:
      1. If there is a resultType and it is Object[].class we do a "pass
      thru"
      2. If there is a resultType and it is Tuple.class we do use a
      RowTransformer adapter that builds a Tuple
      3. If there is just one selection we transform the Object[] by
      returning just row[0]
   2. a RowTransformer adapter for TupleTransformer, if specified

And just a word on dynamic-instantiation here.. it is actually done prior
to any of this.  In fact, in 6.0 a dynamic-instantiation is no different
that other selectable expressions.



On Tue, Sep 13, 2016 at 9:19 AM Steve Ebersole <steve at hibernate.org> wrote:

> So again, this all boils down to the interplay with
> (Result|Tuple|ResultList)Transformer, dynamic instantiations, and
> result-types.
>
> So let's look at some specific cases...
>
> First some cases I think are perfectly valid:
>
> session.createQuery( "select new map(...) ...", Map.class ) - returns a
> List<Map<String,?>>
> session.createQuery( "select new list(...) ...", List.class ) - returns a
> List<List> (rather than List<Object[]>)
> session.createQuery( "select new DTO(...), DTO.class ) - returns a
> List<DTO>
>
> Ok, so I cheated there by not including transformers :)  So let's look at
> adding transformers into this mix[1].
>
> session.createQuery( "select new map(...) ...", Map.class )
>         .setTupleTransformer( new TupleTranformer<SomeNonMap>() {...} )
>
> this one is illegal.  It defines the Query resultType as Map, but the
> applied TupleTranformer is transforming those to SomeNonMap -> CCE.  This
> should be either:
>
> session.createQuery( "select new map(...) ...", SomeNonMap.class )
>         .setTupleTransformer( new TupleTranformer<SomeNonMap>() {...} )
>
> or (non-typed):
>
> session.createQuery( "select new map(...) ..." )
>         .setTupleTransformer( new TupleTranformer<SomeNonMap>() {...} )
>
> In both of those cases, the TupleTranformer is handed a Object[] where
> the only element is the Map.
>
> I guess too that defines the blueprint for what is and what is not
> supported and how the various pieces apply.
>
>
> But I am still not sure about the semantic wrt TupleTransformer and/or
> dynamic-instantiation in combination with Tuple.  I kind of think those
> should just be illegal combos:
>
> session.createQuery( "select ...", Tuple.class )
>         .setTupleTransformer( () -> ... )
>
> Unless the TupleTransformer is building a Tuple, I that is a bad combo for
> sure.
>
> I thik dynamic-instantiation and TupleTransformer is ok:
>
> session.createQuery( "select new DTO(...) ..." )
>         .setTupleTransformer( () -> ... )
>
> Here the TupleTransformer would get Object[] with the long element being
> the DTO; the "query result" is whatever the TupleTransformer returns.
>
> Any other specific combos we should clarify?
>
>
>
> [1]  I am using the new TupleTransformer and ResultListTransformer
> breakdowns I have defined on 6.0 :
> https://gist.github.com/sebersole/bc721caa20a5e4a97cbde44567b0b2ea
>
>
>
> On Tue, Sep 13, 2016 at 8:52 AM Steve Ebersole <steve at hibernate.org>
> wrote:
>
>> On Tue, Sep 13, 2016 at 2:26 AM Gunnar Morling <gunnar at hibernate.org>
>> wrote:
>>
>>> > Between dynamic-instantiation, Tuple-handling...
>>>
>>> To be sure, WDYM by "tuple-handling"?
>>>
>>
>> javax.persistence.Tuple
>>
>> So I gave just one example earlier of how all of these things do not
>> necessarily fit together in inherently obvious ways.  Some combinations
>> I think are ok; others are not.  In sitting here and trying to describe
>> this to a user from a documentation perspective, it is not a simple
>> explanation.
>>
>> I'll follow up with a separate reply that covers those combos for
>> discussion.
>>
>>
>> One use case for result transformers are full-text searches executed
>>> through Hibernate Search's Session extension FullTextSession (see [1]).
>>>
>>> For full-text searches we don't use HQL/JPQL, so the "new ..." syntax
>>> cannot be used, but I don't know about tuple-handling.
>>>
>>
>> Well for sure you do not allow the user to use HQL/JPQL.  But I'd have to
>> assume that under the covers you handle resolving that FullTextQuery
>> yourself from the indexes - which means this is not even a ORM Query at all
>> and what we do with ResultTransformer in ORM in regards to Query is
>> completely irrelevant for you.  In other words I would have to think that
>> Search itself is applying that ResultTransformer in your example, not ORM.
>> Very different.
>>
>


More information about the hibernate-dev mailing list