tags:

views:

1637

answers:

4

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?

+1  A: 

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
Just as an aside, you can use List/SortedList, Set/SortedSet, Map/SortedMap, Collection/Bag, and primitive-array for grouping objects with Hibernate.
Elie
+1  A: 

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.

Michael Borgwardt
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?
KG
+1  A: 

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
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).
KG
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).
KG
A: 

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
Thanks, erickson. That's the answer I needed.
KG