Tuesday, March 24, 2009

Hibernate AliasToBean Transformer

Problem: You need to access values from tables that are not hibernate entities, in an aplication that uses hibernate to access the database.

Problem: You want to access a couple columns from any number of tables in your database without bringing back all the associated objects.

Solution: AliasToBean Transformer allows you to retrieve specific information in non entity beans.

This hibernate API call will allow you to run sql against your database and populate a list of pojos that are not a hibernate entity. This technique is great when you need specific information or perhaps you want information fom multiple tables.


Your pojo:

Class PlainOldObject {
String s1;
String s2;

public String getS1() {return s1;}
public String getS2() {return s2;}

public void setS1(String s1) {this.s1=s1;}
public void setS2(String s2) {this.s2=s2;}

}

Then in a hibernate dao :

publc List lookupPlainOldObects() {

// the sql with a reference to the s1 and s2 fields in our object
String sql="select tableX.col1 as s1, tableY.colx as s2 where blah blah blah";

List list = getCurrentSession().createSQLQuery(sql)
.addScalar("s1")
.addScalar("s2")
.setResultTransformer(Transformers.aliasToBean(PlainOldObject.class ) )
.setCachMode(CacheMode.GET)
.list();

return list;

}

This avoids your needing to cycle over multiple objects to pull in the information you need. It also alleviates the need to cycle over Object[] s to sort through your results.

A couple notes:

1. Use the set scalar method to convert the variables in your sql to the fields in your pojo.
2. Use CacheMode.GET to keep these ojects out of the hibernate session cache.




3 comments:

Fil said...

Ciao!
I read your post and I found it very useful. But I would like to ask something, is it possible to use a transformer to have a bean even obtaining the query result using the scroll() method? I was able to use the aliasToBean trasformer issuing a list() but just changing it to scroll() when I navigate the scrollableresults I just obtain an array of objects. Any hints?
Thanks
Fil

Anonymous said...

Hibernate bug: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3694

Bâtlan Alexandru said...

Thanks very much for your post!

The trick that did it for me was this one:
.addScalar("s1")
.addScalar("s2")


I was doing all well until I found out that all my beans had all their values equal to null or their respective default primitive value.

Without using the addScalar function, no field is populated.

The downside is that the field names are hard-coded and if some day a new field is added to the resulting bean, or a field is renamed, a bug would appear imperceptibly.

Cheers!