Annoying issue, integrating with Hibernate

174 views
Skip to first unread message

LoneWolf

unread,
Dec 7, 2008, 4:54:09 AM12/7/08
to Google Web Toolkit
Hey,
Our application is using Hibernate 3 as the persistence mechanism, and
of course we have one-to-many relationship.
The problem is when trying to pass a domain object that has a list of
lazy initialized objects back to the browser, I got this exception:
++++
Caused by: com.google.gwt.user.client.rpc.SerializationException: Type
'org.hibernate.collection.PersistentSet' was not included in the set
of types which can be serialized by this SerializationPolicy or its
Class object could not be loaded. For security purposes, this type
will not be serialized.
++++
Yes, I understand this exception but to overcome this issue?
Thanks.

gregor

unread,
Dec 7, 2008, 7:05:55 AM12/7/08
to Google Web Toolkit
Hi,

PersistentSet is one of Hibernate's "magic collections". Like the
proxies that Hibernate also uses for lazy loading, domain objects so
adorned are incompatible with the GWT Emulation library and AFAIK
there is no direct way around it at the moment. You have to copy them
to DTO representations for transfer and copy them back on return.

Hibernate4gwt does this for you - have you had a look at it?

regards
gregor

Arthur Kalmenson

unread,
Dec 8, 2008, 2:55:54 PM12/8/08
to Google-We...@googlegroups.com
It's also possible to force it to use a HashSet by copying the
contents of the PersistentSet to a new HashSet. That worked for us.

--
Arthur Kalmenson

Greg

unread,
Dec 8, 2008, 5:15:21 PM12/8/08
to Google Web Toolkit
I do the same exact trick, but I convert a PersistentBag to an
ArrayList.

The tricky part is figuring out where to put your "copy" code so that
it doesn't get in the way or complicate your existing code. I use a
custom field serializer, which is an undocumented feature of GWT.

If you have an object, say Foo, you can customize the GWT RPC
serialization for Foo by creating a class in the same package as Foo,
called Foo_CustomFieldSerializer. Then you add two static methods to
the class as follows:

public static void serialize(SerializationStreamWriter writer, Foo
instance) throws SerializationException {

}

public static void deserialize(SerializationStreamReader reader, Foo
instance) throws SerializationException {

}

Then for every field, you call the appropriate methods in the writer
or reader to serialize or deserialize. Here's the cool part. When
you encounter a collection managed by Hibernate, you can simply swap
out the collection for a GWT safe implementation. So if Foo has a one
to many collection called bars (say it's a List), you can safely
serialize it with the following code:

public static void serialize(SerializationStreamWriter writer, Foo
instance) throws SerializationException {
...
writer.writeObject(new ArrayList(instance.getBars()));
...
}

and the deserialization is just as easy

public static void deserialize(SerializationStreamReader reader, Foo
instance) throws SerializationException {
...
instance.setBars((List)reader.readObject());
...
}

The best part about using a custom field serializer is that your
original object does not get modified. I tried an approach where I
swapped out the collection just prior to returning from my RPC
method. This caused two problems. First it complicated the code.
Second, Hibernate detected a change to my object and persisted it.
This wasn't a huge problem, but it did cause an unnecessary write to
the database.

I also looked into Hibernate4GWT. But I found that if you don't need
to do lazy loading of persistent collections on the client side, then
Hibernate4GWT is overkill.

-Greg
> >> Thanks.- Hide quoted text -
>
> - Show quoted text -

Martin Trummer

unread,
Dec 9, 2008, 4:33:07 AM12/9/08
to Google Web Toolkit
you should take a look at:
http://noon.gilead.free.fr/gilead (formerly known as hibernate4gwt)

noon

unread,
Dec 9, 2008, 5:29:22 AM12/9/08
to Google Web Toolkit
Just a precision : Hibernate4Gwt/Gilead *does not* lazy load any
association from client side (it would lead to very poor
performances !!!).
It just take care of lazy but not loaded associations and persistent
collections during serialization and deserialisation process.

Another thing to know is that almost all of the above "quick"
solutions does not work in all cases : just try to send a partially
loaded entity on client side (=> Serialization Exception) or modify a
collection in GWT code (exception or no effect on server-side)...

Regards
Bruno

Greg

unread,
Dec 9, 2008, 10:41:24 AM12/9/08
to Google Web Toolkit
Sorry for the inaccurate info about Hibernate4Gwt, it's been a while
since I looked at it.

I would agree that depending on how you use Hibernate, the quick
solution may or may not work for you. While my objects are not always
fully populated on the server, the serialization process forces them
to populate. Also, when saving on the client side I always send back
a full graph of objects to the server. So any additions made to my
collections do show up on the server and get persisted. I admit that
deletes from a collection do not work using this approach. To get
deletes working, objects need to be marked for delete on the client
and then removed from the collection on the server after reattaching
to the session. But I think this is a common problem when working in
a detached state.

-Greg
> > > - Show quoted text -- Hide quoted text -
Reply all
Reply to author
Forward
0 new messages