3

Does the Hibernate API support object result sets in the form of a collection other than a List?

For example, I have process that runs hundreds of thousands of iterations in order to create some data for a client. This process uses records from a Value table (for example) in order to create this output for each iteration.

With a List I would have to iterate through the entire list in order to find a certain value, which is expensive. I'd like to be able to return a TreeMap and specify a key programmatically so I can search the collection for the specific value I need. Can Hibernate do this for me?

karlgrz
  • 14,485
  • 12
  • 47
  • 58
  • Is there a reason you can't specify your criteria in the where clause? – Sarel Botha Jan 06 '09 at 15:35
  • I'm trying to pull the whole set of objects that I want to work with into memory so I can cut down on calls to the database. If I call a SELECT for each iteration I'm looking at hundreds of thousands of calls, which is running horrifically slow. – karlgrz Jan 06 '09 at 15:40
  • "so I can cut down on calls to the database" - it doesn't appear to be working, since you have hundreds of thousands of calls. You either need some smarter queries or a better caching solution. – duffymo Jan 07 '09 at 11:08
  • Check accepted answer for this question: http://stackoverflow.com/a/118976/775523 – dbf May 31 '12 at 07:36

4 Answers4

2

If I understand correctly, you load a bunch of data from the database to memory and then use them locally by looking for certain objects in that list.

If this is the case, I see 2 options.

  1. Dont load all the data, but for each iteration access the database with a query returning only the specific record that you need. This will make more database queries, so it will probably bu slower, but with much less memory consumption. This solution could easily be improved by adding cache, so that most used values will be gotten fast. It will of course need some performance measurement, but I usually favor a naive solution with good caching, as the cache can implemented as a cross-concern and be very transparent to the programmer.
  2. If you really want to load all your data in memory (which is actually a form of caching), the time to transform your data from a list to a TreeMap (or any other efficient structure) will probably be small compared to the full processing. So you could do the data transformation yourself.

As I said, in the general case, I would favor a solution with caching ...

Guillaume
  • 18,494
  • 8
  • 53
  • 74
  • Solution 1 is exactly how I have my code set up right now. The number of queries to the database is slowing execution time to unacceptable levels (this code is run for every county in the US...3141 times potentially hundreds of thousands of iterations). – karlgrz Jan 06 '09 at 15:48
  • Perhaps my caching solution is set up incorrectly, as even when I have caching set up I still see queries being executed using SQL Profiler (SQL Server database). – karlgrz Jan 06 '09 at 15:49
2

I assume you are referring to the Query.list() method. If so: no, there is no way to return top-level results other than a List. If you are receiving too many results, why not issue a more constrained query to the database? If the query is difficult to constrain, you can populate your own Map with the contents of Hibernate's List and then throw away the list.

erickson
  • 265,237
  • 58
  • 395
  • 493
1

From Java Persistence with Hibernate:

  • A java.util.Map can be mapped with <map>, preserving key and value pairs. Use a java.util.HashMap to initialize a property.
  • A java.util.SortedMap can be mapped with <map> element, and the sort attribute can be set to either a comparator or natural ordering for in-memory sorting. Initialize the collection with a java.util.TreeMap instance.
Elie
  • 13,693
  • 23
  • 74
  • 128
  • Just as an aside, you can use List/SortedList, Set/SortedSet, Map/SortedMap, Collection/Bag, and primitive-array for grouping objects with Hibernate. – Elie Jan 06 '09 at 15:37
1

Yes, that can be done.

However, you'll probably have to have your domain class implement Comparable; I don't think you can do it using a Comparator.

Edit: It seems like I misunderstood the question. If you're talking about the result of an ad hoc query, then the above will not help you. It might be possible to make it work by binding an object with a TreeMap property to a database view if the query is fixed.

And of course you can always build the map yourself with very little work and processing overhead.

casperOne
  • 73,706
  • 19
  • 184
  • 253
Michael Borgwardt
  • 342,105
  • 78
  • 482
  • 720
  • Interesting...does this mean that I would need to write a wrapper class for the object that is representing my table? For example, ValueMap which contains a map of Value objects? Or does Hibernate have a specific method instead of list() to return the results? – karlgrz Jan 06 '09 at 15:44