The problem:

When i am selecting a full table,

i.e. select * from product

Hibernate returns me a list of Product objects. However, when i am selecting only a subset of it,

i.e. select name, price from product

Hibernate returns me a list of objects which it is unable to cast it into a list of Product objects out of the box. Any attempts to cast it into a list of Product objects causes ClassCastException.

@SuppressWarnings("unchecked")
@Override
public List<UserRoleAndProgramCategory> get(int roleId, int programCategoryId) {
    String sHql;
    String[] key;
    Object[] value;

    key = new String[] { "roleId", "programCategoryId" };
    value = new Integer[] { roleId, programCategoryId };

    sHql = "select distinct l.userId, l.userName, l.fullName, l.roleId, l.roleName, l.roleCode, l.programCategoryId, l.programCategoryCode, l.programCategoryDescription from "
            + UserRoleAndProgramCategory.class.getName()
            + " as l where roleName <> ' ' and roleCode not in ('CONTRACTOR', 'ADMIN') and programCategoryId = :programCategoryId and roleId = :roleId";

    return (List<UserRoleAndProgramCategory>) super.getQueryWithCache(sHql, key, value, false, false, false)
            .getQueryResult();
}

The solution

I modified the SQL query such that Hibernate may cast the retrieved result set into the business domain object for me.

sHql = "select distinct new UserRoleAndProgramCategory(l.userId, l.userName, l.fullName, l.roleId, l.roleName, l.roleCode, l.programCategoryId, l.programCategoryCode, l.programCategoryDescription) from "
            + UserRoleAndProgramCategory.class.getName()
            + " as l where roleName <> ' ' and roleCode not in ('CONTRACTOR', 'ADMIN') and programCategoryId = :programCategoryId and roleId = :roleId";

In the constructor of UserRoleAndProgramCategory class, i have crafted a constructor that “fits” exactly with the query.

public class UserRoleAndProgramCategory implements IUserRoleAndProgramCategory, Serializable {
	...

	public UserRoleAndProgramCategory(int userId, String userName, String fullName, int 	roleId, String roleName, String roleCode, int programCategoryId, String 	programCategoryCode, String programCategoryDescription) {
		this.userId = userId;
		this.userName = userName;
		this.fullName = fullName;
		this.roleId = roleId;
		this.roleName = roleName;
		this.roleCode = roleCode;
		this.programCategoryId = programCategoryId;
		this.programCategoryCode = programCategoryCode;
		this.programCategoryDescription = programCategoryDescription;
	}
	...
}


This is one of the few ways, and somewhat not elegant, i will follow up this solution with the better alternative once i have more time after this bug fix period.


Reference

http://stackoverflow.com/questions/4917677/when-selecting-a-subset-of-a-table-hibernate-does-not-auto-cast-it-into-the-busi/

http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#queryhql-select

http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#d0e17601

Share