@NamedQuery on non-entities

I would like to know if and how I can define @NamedQuery annotations on non-entity classes and get them scanned on session factory creation. I’ve read somewhere that this is possible in Hibernate 6 but I haven’t found any examples on how to achieve it and frankly I cannot seem to find the statement itself, so I might have misread something.

In Hibernate 5, I used a class scanner to find classes with @NamedQuery annotations on it and feed it into the session factory. This allowed me to put the queries on the services where they are actually used. The limitation to put the queries on an entity led to huge entity classes. It was just not a viable approach for an application with over 2000 service classes using decentralized named queries.

Yet, with Hibernate 6, I don’t seem to get it working. Only the named queries on the entity classes are considered. What am I missing here?

You can add the queries on a package in a package-info.java within which one of your managed objects is in. Not sure in what environment you’re running, but it’s also possible to add an explicit package to be scanned with org.hibernate.cfg.Configuration#addPackage.

I’m running Hibernate 6.6 in a Spring 5.3 environment. So I could pass the packages to Configuration.

However, it is not the most optimal solution. I would like to have the queries on the Service where I use them. The package would be something I could live with as a temporary alternative but not as a final solution because it is still decentralized and limited.

Only the hibernate annotations are allowed on packages. I use a lot of SqlResultSetMapping annotations which are from the jakarta.persistence namespace and they are only allowed on types.

Meanwhile, I have decided to stick with my “old” solution in order to prevent moving the massive amount of queries to package-info. I’m now using the spring classpath scanner again to detect the annotations and feed them to the Hibernate NamedObjectRepository immediately after building the SessionFactory.

Actually I’m curious why it was decided to only allow named (native) queries in entity classes and package-info. The Hibernate class scanner visits every class in the package structure it is configured to look anyway. From what I’ve seen in the code it’s not a big deal to implement this additional feature.

It might work when using the Hibernate scanner, but not in other environments. I think the JPA spec lists the annotations that have to be scanned by a container, so unless the object that you want to annotate e.g. @SqlResultSetMapping on also has such a JPA blessed discovery annotation, it’s not going to work portably.

We can of course consider this as an additional Hibernate ORM feature which you are very welcome to bring up in our Zulip Chat platform.