Using @ConstructorResult
will work great once it's available for your persistence layer. Until then, there is a Hibernate-specific approach using an org.hibernate.SQLQuery
and an org.hibernate.transform.ResultTransformer
that does not depend on @SqlResultSetMapping
. Because a POJO is populated, Hibernate finds no @Entity
to automatically turn into a table.
Non-persisted POJO:
public class Foo {
public Long row_id;
public String name;
}
ResultTransformer:
public static class FooResultTransformer implements ResultTransformer {
@Override
public List transformList(List list) { return list; }
@Override
public Object transformTuple(Object[] tuple, String[] aliases) {
List<String> aliasList = Arrays.asList(aliases);
Foo foo = new Foo();
foo.row_id = ((Number) getValue(tuple, aliasList, "row_id", 0L))
.longValue();
foo.name = (String) getValue(tuple, aliasList, "name", null);
return foo;
}
private static Object getValue(Object[] tuple, List<String> aliases,
String field, Object defaultValue)
{
// unchecked for berevity
if (tuple[aliases.indexOf(field)] == null) {
return defaultValue;
}
return tuple[aliases.indexOf(field)];
}
}
Native SQLQuery:
String sql = "SELECT id AS row_id, friendlyName AS name FROM SomeTable";
Session session = JPA.em().unwrap(Session.class);
SQLQuery q = session.createSQLQuery(sql);
q.setResultTransformer( new FooResultTransformer() );
List<Foo> fooList = q.list();