I'm converting the server side of a client-server application to use Hibernate. It is not a web application. I'm using Hibernate 2.1.7 right now, and will use version 3 if anyone thinks it will help with this.
The server application responds to client requests and needs to use Hibernate to get objects (an object graph) from the database. It will then encode them using java.beans.XMLEncoder and send them across a socket to the client app. The client app may send changes back to the server to be processed and saved or it may just view the object and send nothing back.
My problem is that I cannot encode the objects after they are retrieved by Hibernate (nor can I serialize them). The encoding does work on my plain old java objects if I create them myself. Hibernate, however, uses its own collection classes. When I attempt to an object using them, the generated XML does not reference the collection and I get this error:
Code:
Mar 24, 2005 11:51:52 AM net.sf.hibernate.LazyInitializationException <init>
SEVERE: Failed to lazily initialize a collection - no session or session was closed
net.sf.hibernate.LazyInitializationException: Failed to lazily initialize a collection - no session or session was closed
at net.sf.hibernate.collection.PersistentCollection.initialize(PersistentCollection.java:209)
at net.sf.hibernate.collection.PersistentCollection.read(PersistentCollection.java:71)
at net.sf.hibernate.collection.Set.size(Set.java:106)
at java.util.AbstractSet.equals(AbstractSet.java:72)
at java.beans.DefaultPersistenceDelegate.equals(DefaultPersistenceDelegate.java:207)
at java.beans.DefaultPersistenceDelegate.doProperty(DefaultPersistenceDelegate.java:220)
at java.beans.DefaultPersistenceDelegate.initBean(DefaultPersistenceDelegate.java:254)
at java.beans.DefaultPersistenceDelegate.initialize(DefaultPersistenceDelegate.java:395)
at java.beans.PersistenceDelegate.writeObject(PersistenceDelegate.java:103)
at java.beans.Encoder.writeObject(Encoder.java:55)
...
If I pull the set and encode it, the XML contains no trace of the contained objects and looks like this:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.4.2_05" class="java.beans.XMLDecoder">
<object class="net.sf.hibernate.collection.Set">
<void property="collectionSnapshot">
<object class="net.sf.hibernate.impl.SessionImpl$CollectionEntry"/>
</void>
</object>
</java>
So, I think I need a Hibernate-independent POJO that uses java.util collections. Can I get that from the loaded object? Is there a way to do this?
I could put a resetAllCollections() method on each object that empties the contents of the Hibernate collections into java.util collections, but that seems like a big imposition on the domain by the persistence layer.
Alternately, is there a way to turn off this proxying?
I know there are good reasons for Hibernate to use its own collections and I'm prepared for a performance hit and having to use select-before-update or something to let Hibernate figure out what has changed. If I can't get objects to clients from the server, though, it doesn't matter how quickly it might save them :)
Any help is greatly appreciated,
Scott