views:

535

answers:

5

If there are many return records from DB. It will get stackoverflow problem. User is a class, which has a one to many relationship (to 3 other classes). When I print out the SQL, i found that the system runs the same query many time to get the data from DB. Does anyone know what the problem is?

      result.addAll(getCurrentSession().createCriteria(User.class)
   .add(Restrictions.ilike("name", "tom", MatchMode.ANYWHERE))
   .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
   .list());
A: 

I don't understand the question

Supernovah
Comments are a better place for such replies, since it's not really an answer!
dbr
A: 

If you are looking for users with tom in the name only then it shouldn't run out of memory unless you have a lot of %tom% hehe.

You could try to put a limit on it so it only returns some that you can handle at a time.

I am not sure anyone can figure out why its running the same query without more information.

Arthur Thomas
A: 

By any chance, are you using EntityMode.DOM4J ? (i.e. Hibernate --> XML instead of Hibernate --> POJO). Nested relationships do not work without tweaking because the XML generator infinitely recurses where as POJOS handle it them fine.

I can elaborate, but if you're not using DOM4J, then the issue is something else.

Nicholas
A: 

Hi Nicholas,

could you please explain the EntityMode.DOM4J problem with nested relationships? That's exactly my problem: I'm using Hibernate in DOM4J entity mode and get a stack overflow when using the dom4j XML writer.

Thank you in advance for any explanation!

A: 

It would help to know exactly what repeated queries that you're seeing. As others pointed out, we're just speculating without seeing your mappings. You might be running into Hibernate's eager fetching. This is where Hibernate tries to load an entire object graph for every User (and their Addresses, Phones, Pets, etc.) matching the very general name contains 'tom' query. Try turning off default eager fetching for User properties in your Hibernate mapping files or annotations and then do the following:

Let's say you're getting lots of repeated queries looking into the tables USER_ADDRESS (hibernate property "addresses"), USER_PHONE (property "phones"), and USER_PET (property "pets"). Use the following criteria calls to join these attributes in the original query and reduce repeated queries. Hibernate knows how to break these columns apart into separate objects. You can also try adding a maximum number of returned results.

Criteria myUsers = getCurrentSession().createCriteria(User.class);
myUsers = myUsers.add(Restrictions.ilike("name", "tom", MatchMode.ANYWHERE));
myUsers.createCriteria("addresses"); // NEW
myUsers.createCriteria("phones"); // NEW
myUsers.createCriteria("pets"); // NEW
myUsers.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
myUsers.setMaxResults(100); // NEW
result.addAll(myUsers.list());

You can learn more in sections 15.4-15.6 here: http://docs.jboss.org/hibernate/core/3.3/reference/en/html/querycriteria.html#querycriteria-associations

Barett