Hibernate behaves differently when using Query.list() and Query.iterate(). When you use Query.iterate(), Hibernate will issue a SQL query that will fetch only the IDs. When you iterate over the results, it will load the entity lazily. Query.iterate() is an optimization for the Level 2 cache. By loading only the IDs, it can quickly get the entity from the second level cache if its there, otherwise it hits the database. If you're not using a second level cache, Query.iterate() will be much slower than Query.list().
Now, when you execute your code:
Code:
Query q = session.createQuery("from MyObject mo ");
Iterator i = q.iterate();
while (i.hasNext())
{
Object o = i.next();
System.out.println(o.getClass().getName());
}
The iteration only contains proxies to the orginal object. Because you did not access any properties on the object, the instance was not loaded, thus what you are seeing. If you changed your code to something like:
Code:
Query q = session.createQuery("from MyObject mo ");
Iterator i = q.iterate();
while (i.hasNext())
{
Object o = i.next();
o.getSomeProperty(); //-- this will trigger a DB load.
System.out.println(o.getClass().getName()); //-- this will now print out the actual class name
}
You'll see hibernate issue a SELECT for that ID and the class name should not be a proxy. If changed your code to user q.list().iterator(), you'd avoid the issue all together.
Lastly, if you want to get the actual class name of a proxy, you can do something like this:
Code:
if (object instanceof HibernateProxy){
HibernateProxy proxy = (HibernateProxy) object;
return proxy.getHibernateLazyInitializer().getImplementation();
}
Hope this clears things up.
Ryan-