Reputation: 6162
I would like to fetch multiple Hibernate mapped objects from a database in a batch. As far as I know this is not currently supported by Hibernate (or any Java ORM I know of). So I wrote a driver using RMI that implements this API:
interface HibernateBatchDriver extends Remote
{
Serializable [] execute (String [] hqlQueries) throws RemoteException;
}
The implementation of this API opens a Hibernate session against the local database, issues the queries one by one, batches up the results, and returns them to the caller. The problem with this is that the fetched objects no longer have any Session
attached to them after being sent back, and as a result accessing lazily-fetched fields from such objects later on ends up with a no session error. Is there a solution to this problem? I don't think Session
objects are serializable otherwise I would have sent them over the wire as well.
Upvotes: 0
Views: 163
Reputation: 15250
Hibernate Session objects are Serializable
. The underlying JDBC connection is not. So you can disconnect() the session from the JDBC connection before serialization and reconnect() it after deserialization.
Unfortunately this won't help you very much if you need to send the session to a host where you can't obtain a new JDBC connection. So the only option is to fully load the objects, serialize and send them to the remote host.
Upvotes: 1
Reputation: 3942
As @dcernahoschi mentioned, Session
object is Serializable
, but the JDBC connection is not. Serializable means that you save something to a file, later you read it and it's the same object. You can't save a JDBC connection to a file, and restore it later from that file. You should have to open a new JDBC connection.
So, even though you could send the session via RMI, you would need JDBC connection in the remote computer as well. But if it was possible to setup a session in the remote computer, then why not execute the queries in that computer?
If you want to send the query results via RMI, then you need to do is fetch the whole objects without lazily fetching. In order to do that you must define all relationships as eagerly fetched in your mappings.
If you can't change the mappings to eager, then there is an alternative to get a "deep" copy of each object and send this object through RMI. Creating a deep copy of your objects will take some effort, but if you can't change the mapping to eager fetching it is the only solution. This approach means that your interface method must change to something like:
List[] execute (String [] hqlQueries) throws RemoteException;
Each list in the method result will keep the results fetched by one query.
Upvotes: 1