The best way to use the Hibernate TupleTransformer
Are you struggling with performance issues in your Spring, Jakarta EE, or Java EE application?
What if there were a tool that could automatically detect what caused performance issues in your JPA and Hibernate data access layer?
Wouldn’t it be awesome to have such a tool to watch your application and prevent performance issues during development, long before they affect production systems?
Well, Hypersistence Optimizer is that tool! And it works with Spring Boot, Spring Framework, Jakarta EE, Java EE, Quarkus, Micronaut, or Play Framework.
So, rather than fixing performance issues in your production system on a Saturday night, you are better off using Hypersistence Optimizer to help you prevent those issues so that you can spend your time on the things that you love!
Introduction
In this article, I’m going to explain how the Hibernate TupleTransformer works and how to use it to replace the deprecated ResultTransformer.
The deprecated ResultTransformer
Prior to using Hibernate 6, the ResultTransformer was the default option for transforming a query result set.
However, since 5.2, the setResultTransformer method of the Hibernate Query interface was deprecated even if no alternative was provided at the time. The reason why this method and its associated ResultTransformer interface were deprecated was that the ResultTransformer interface was not a functional interface.
A functional interface provides a single abstract method and can be used when defining a lambda expression. For this reason, the legacy ResultTransformer interface was split into two interfaces TupleTransformer and ResultListTransformer, as illustrated in the following diagram:

Hibernate TupleTransformer
The TupleTransformer defines the transformTuple method, as follows:
@Incubating
@FunctionalInterface
public interface TupleTransformer<T> {
/**
* Tuples are the elements making up each "row" of the query result.
* The contract here is to transform these elements into the final
* row shape.
*
* @param tuple The result elements
* @param aliases The result aliases ("parallel" array to tuple)
*
* @return The transformed row.
*/
T transformTuple(Object[] tuple, String[] aliases);
}
The transformTuple method allows you to transform the default Object[] array projection resulting from the JDBC ResultSet after consuming a given record.
How to use the Hibernate TupleTransformer
For instance, let’s say we have the following Post entity:
@Entity(name = "Post")
@Table(name = "post")
public class Post {
@Id
private Long id;
private String title;
@Column(name = "created_on")
private LocalDateTime createdOn;
@Column(name = "created_by")
private String createdBy;
@Column(name = "updated_on")
private LocalDateTime updatedOn;
@Column(name = "updated_by")
private String updatedBy;
@Version
private Integer version;
}
And we want to execute the following JPQL query, which fetches a custom projection:
select
p.id,
p.title,
p.createdOn,
p.createdBy,
p.updatedOn,
p.updatedBy
from Post p
order by p.id
By default, when executing the JPQL query above, the project records are going to be wrapped in an Object[] array:
List<Object[]> postRecords = entityManager.createQuery("""
select
p.id,
p.title,
p.createdOn,
p.createdBy,
p.updatedOn,
p.updatedBy
from Post p
order by p.id
""")
.getResultList();
However, operating with Object[] array projections is not developer-friendly, so we want to map the query result on the following Java Record hierarchy:

For this purpose, we are going to use a TupleTransformer that allows us to map the default Object[] array projection to the PostRecord object, like this:
List<PostRecord> postRecords = entityManager.createQuery("""
select
p.id,
p.title,
p.createdOn,
p.createdBy,
p.updatedOn,
p.updatedBy
from Post p
order by p.id
""")
.unwrap(org.hibernate.query.Query.class)
.setTupleTransformer(
(tuple, aliases) -> {
int i =0;
return new PostRecord(
longValue(tuple[i++]),
stringValue(tuple[i++]),
new AuditRecord(
localDateTimeValue(tuple[i++]),
stringValue(tuple[i++]),
localDateTimeValue(tuple[i++]),
stringValue(tuple[i++])
)
);
}
)
.getResultList();
Cool, right?
If you enjoyed this article, I bet you are going to love my Book and Video Courses as well.
Conclusion
Hibernate 6 provides a lot of new features, like SQM (Semantic Query Model) or support for Window Functions.
The new Hibernate TupleTransformer should be used to replace the legacy ResultTransformer usages, as the deprecated ResultTransformer will surely be removed in a future version of Hibernate.






