I am new to Hibernate and Hibernate development so I would like to appologize for anything I may do wrong (and for my English as well :) )
I have a requirement to execute custom queries. I couldn't find an appropriate solution except changing Hibernate itself. Thus I added new method to Session class:
Code:
public List callSQL(Class persistentClass, String sql) throws HibernateException;
and implemented it in SessionImpl class like that:
Code:
public List callSQL(Class persistentClass, String sql) throws HibernateException
{
Loadable persister = (Loadable) getPersister(persistentClass);
CustomSQLLoader loader = new CustomSQLLoader(persister, factory, sql);
dontFlushFromFind++;
try
{
return loader.list(this);
}
catch (SQLException sqle)
{
throw new JDBCException(sqle);
}
finally
{
dontFlushFromFind--;
}
}
Then I added a new class:
Code:
public class CustomSQLLoader extends AbstractEntityLoader
{
public CustomSQLLoader(Loadable persister, SessionFactoryImpl factory, String value) throws HibernateException
{
super(persister, factory);
classPersisters = new Loadable[1];
classPersisters[0] = persister;
lockModeArray = createLockModeArray(1, LockMode.NONE);
suffixes = new String[1];
postInstantiate();
sql = value;
}
public List list(SessionImplementor session) throws HibernateException, SQLException
{
RowSelection selection = new RowSelection();
return find(session, new Object[]{}, new Type[]{}, true, selection, null, null);
}
protected Object getResultColumnOrRow(Object[] row, ResultSet rs, SessionImplementor session) throws SQLException, HibernateException
{
return row[row.length - 1];
};
}
Well, that's pretty much it.
You may use it like that:
Code:
List l = session.callSQL(Patient.class, "exec sp_select_patients");
Iterator i = l.iterator();
while (i.hasNext())
{
Patient p = (Patient)i.next();
// do something with a patient
}
It seems to work fine, but I'm not sure that I didn't ruin anything and, ergo, I have a question (two of them to be precise): is there any way to execute custom queries in existing version of Hibernate and if not is my way of doing it correct?