Red Hat
Mar 1, 2016
by Gunnar Morling

During my talk at VoxxedVienna on using Hibernate Search with Elasticsearch earlier this week, there was an interesting question which I couldn’t answer right away:

"When running a full-text query with a projection of fields, is it possible to return the result as a list of POJOs rather than as a list of arrays of Object?"

The answer is: Yes, it is possible, result transformers are the right tool for this.

Let’s assume you want to convert the result of a projection query against the VideoGame entity shown in the talk into the following DTO (data transfer object):

public static class VideoGameDto {
      
          private String title;
          private String publisherName;
          private Date release;
      
          public VideoGameDto(String title, String publisherName, Date release) {
              this.title = title;
              this.publisherName = publisherName;
              this.release = release;
          }
      
          // getters...
      }

This is how you could do it via a result transformer:

FullTextEntityManager ftem = ...;
      
      QueryBuilder qb = ftem.getSearchFactory()
          .buildQueryBuilder()
          .forEntity( VideoGame.class )
          .get();
      
      FullTextQuery query = ftem.createFullTextQuery(
          qb.keyword()
              .onField( "tags" )
              .matching( "round-based" )
              .createQuery(),
          VideoGame.class
          )
          .setProjection( "title", "publisher.name", "release" )
          .setResultTransformer( new BasicTransformerAdapter() {
              @Override
              public VideoGameDto transformTuple(Object[] tuple, String[] aliases) {
                  return new VideoGameDto( (String) tuple[0], (String) tuple[1], (Date) tuple[2] );
              }
          } );
      
      List<VideoGameDto> results = query.getResultList();

I’ve pushed this example to the demo repo on GitHub.

There are also some ready-made implementations of the ResultTransformer interface which you might find helpful. So be sure to check out its type hierarchy. For this example I found it easiest to extend BasicTransformerAdapter and implement the transformTuple() method by hand.

To the person asking the question: Thanks, and I hope this answer is helpful to you!

Original Post