Thinking again, maybe a better way would be to have a special projection, say "RootEntityProjection", that mimics the behavior of "entity.*", i.e., it would automatically expand all properties of the specified entity.
This way, we could combine RootEntityProjection with SQLProjection, something like this:
.add(Projections.rootEntityProjection(Entity.class, "entity")) // this would expand into all root entity properties, aliased
.add(Projections.sqlProjection("dbFunction() as alias", ..., ...)) // this would call dbFunction()
I'm using alias-based ResultTransformer, so we must use aliases like property names, but you could enhance implicit org.hibernate.criterion.CriteriaSpecification#PROJECTION to take care of this.
And, of course, I am assuming we have a transient property declared in the entity to receive the dbFunction() result.
This behavior seems pretty much like when we use the @Formula annotation, except that in many situations, we want that to be dynamic, i.e., we don't always want to call the same database function or some times we don't want to call any database function at all. Additionally, a database function may have parameters and @Formula doesn't allow variables, only constants.
Any thoughts on this?