The JPQL select new syntax originated in the earliest days of Hibernate, providing a way to package a query projection list into a Java object. This was before Java had generics or record types, so you would use it like this:

List list =
        session.createQuery("select new Summary(b.title, b.publicationDate) from Book b")
                .list();
Iterator iter = list.iterator();
while (iter.hasNext()) {
    Summary summary = (Summary) iter.next();
    ...
}

This thing found its way into JPA 1.0 with essentially no change.

JPA 2.0 introduced support for Java generics, which lead to this variation:

List<Summary> list =
        session.createQuery("select new Summary(b.title, b.publicationDate) from Book b", Summary.class)
                .getResultList();
for (Summary summary : list) {
    ...
}

And then nothing else changed for more than a decade.

In Hibernate 6, I decided to streamline this. In recent releases of Hibernate ORM it’s been possible to write:

var list =
        session.createQuery("select title, publicationDate from Book", Summary.class)
                .getResultList();
for (var summary in list) {
    ...
}

Since we’re explicitly passing the return type to createQuery(), Hibernate can infer the select new bit. This even works in Hibernate Data Repositories, where we can write a repository method like this:

@Query("select title, publicationDate from Book")
List<Summary> summaries();

The Java language has got better too, and so nowadays you would write the Summary class as a record:

record Summary(String title, LocalDate publicationDate) {}

I’m blogging about all this partly because it’s come to my attention that plenty of you still don’t know about this. It’s a small thing—​one of many, many small things that make Hibernate 6 so much nicer to use.

no select new

The other reason this is something worth blogging about is that I want to make it standard in Jakarta Persistence 4. In fact, we’ve already wrapped up work on including this feature in Jakarta Data, and it’s coming in Data 1.1.


Back to top