Hibernate-generated column aliases break AliasToBeanResultTransformer when using query

Ivaylo Slavov picture Ivaylo Slavov · Apr 4, 2012 · Viewed 11k times · Source

What I am trying to achieve is to set a result transformer on a query defined in the following way:

String hqlQueryString = "select o.id as id, o.name as objectName from MyObject"; 
Class resultClass = MyObject.class;
Query query = session.createQuery(hqlQueryString).setResultTransformer(
        new new AliasToBeanResultTransformer(resultClass));
List result = query.list();

MyObject looks like this:

public class MyObject {
    private int id;
    private String objectName;

    public int getId() {
        return id;
    }
    public void setId(int value) {
        this.id = value;
    }

    public String getObjectName() {
        return objectName;
    }
    public void setobjectName(String value) {
        this.objectName = value;
    }
}

The problem is, that although I have specified id and objectName to be my aliases, the actual query being executed uses different aliases. This causes my AliasToBeanResultTransformer to fail to construct MyObject because the aliases do not match property names.

Is it possible to obtain the aliases of the query generated by hibernate programmatically (I can set them to the alias to bean result tranformer)? I tried using query.getReturnAliases() but it returns the aliases that I have defined in my HQL, not the ones that Hibernate actually uses.

Can I explicitly specify the aliases in a createQuery statement? Currently I am trying not to use criterion for this to work, so I'd appreciate an approach that uses query objects, if such exists.


Update

Although the issue described above is invalid for standard HQL queries (see comments), it is valid when executing a native query. To be specific - native queries seemed to treat all aliases as lowecase strings (despite specific capitalization that might have been introduced in the query). This causes the AliasToBeanResultTransformer to fail when setting the properties, in cases where capitalization matters.

Answer

Ken Chan picture Ken Chan · Apr 5, 2012

Actually don't need to implement another AliasToBeanResultTransformer , you can use addScalar(String columnAlias, Type type) to explicitly alias the columns of the native SQL:

String nativeSQL = "select o.id as id, o.name as objectName from MyObject"; 
List<MyObject> resultList = session.createSQLQuery(nativeSQL)
        .addScalar("id" ,StandardBasicTypes.INTEGER)
        .addScalar("objectName",StandardBasicTypes.STRING)
        .setResultTransformer(new AliasToBeanResultTransformer(MyObject.class))
        .list();

The transformer will then look for a MyObject class and expect it having the setters setId() and setObjectName() in order to populate the returned values to the MyObject instance