PersistentBag_CustomFieldSerializer for org.hibernate.collection.PersistentBag

518 views
Skip to first unread message

Sanj

unread,
Aug 20, 2008, 11:13:52 AM8/20/08
to Google Web Toolkit
Hello All,


I want to use Hibernate. But as all know there is some problem in
Serialization i.e. GWT serialization policy not supported
PersistentBag. I have read somewhere write your Serialization class
like

package com.google.gwt.user.client.rpc.core.org.hibernate.collection;

import java.util.Iterator;

import com.google.gwt.user.client.rpc.SerializationException;
import com.google.gwt.user.client.rpc.SerializationStreamReader;
import com.google.gwt.user.client.rpc.SerializationStreamWriter;

/**
* Custom field serializer for {
*
* @linkorg.hibernate.collection.PersistentList}.
*/
public final class PersistentBag_CustomFieldSerializer {

public static void deserialize(SerializationStreamReader
streamReader, org.hibernate.collection.PersistentBag instance) throws
SerializationException {
int size = streamReader.readInt();
for (int i = 0; i < size; ++i) {
Object obj = streamReader.readObject();
instance.add(obj);
}
}

public static void serialize(SerializationStreamWriter streamWriter,
org.hibernate.collection.PersistentBag instance) throws
SerializationException {
int size = instance.size();
streamWriter.writeInt(size);
Iterator iter = instance.iterator();
while (iter.hasNext()) {
Object obj = iter.next();
streamWriter.writeObject(obj);
}
}

}


But there is also some problem org.hibernate.collection.PersistentBag
in client package. How can i solve this?



Ian Petersen

unread,
Aug 20, 2008, 11:18:17 AM8/20/08
to Google-We...@googlegroups.com
On Wed, Aug 20, 2008 at 11:13 AM, Sanj <sunil....@daffodildb.com> wrote:
> How can i solve this?

Convert your PersistentBag to an ArrayList before giving it to the client.

Ian

Sanj

unread,
Aug 20, 2008, 11:54:27 AM8/20/08
to Google Web Toolkit
That is also one another solution for handling PersistentBag. But
there is also some problem for e.g.

if you have collection of B's in class A and B also contains object of
A then that occurs the stackOverFlowError. This cyclic case may occur
in as deeper. Then we can't convert whole object at a time.

For solution of that problem, fetch object upto any defined chaining
Level. But upto one level when it returns Null then it also throup
PersistentBag not serializable exception.

On Aug 20, 8:18 pm, "Ian Petersen" <ispet...@gmail.com> wrote:

Ian Petersen

unread,
Aug 20, 2008, 12:19:36 PM8/20/08
to Google-We...@googlegroups.com
On Wed, Aug 20, 2008 at 11:54 AM, Sanj <sunil....@daffodildb.com> wrote:
> That is also one another solution for handling PersistentBag. But
> there is also some problem for e.g.
>
> if you have collection of B's in class A and B also contains object of
> A then that occurs the stackOverFlowError. This cyclic case may occur
> in as deeper. Then we can't convert whole object at a time.
>
> For solution of that problem, fetch object upto any defined chaining
> Level. But upto one level when it returns Null then it also throup
> PersistentBag not serializable exception.

I'm not 100% clear what you mean, but I think you're saying that you
have a problem when you have a cyclic object graph and part of that
graph is one or more persistent collections.

You're certainly right that you can't use a tree-based algorithm on a
graph because graphs aren't trees--as soon as you add a cycle, you get
stack overflow problems, not to mention duplicate copies of things.
But you can use a graph-based algorithm on an object graph and come
out with a consistent deep copy that uses standard java.util
collections in place of Hibernate's persistent versions.

I have written my own, purpose-built tool that does the above, but
there are general tools available for download. I think Dozer does
what you want, but I've never used it myself, and you might want to
look at Hibernate4GWT. If you want to roll your own, the basic
algorithm is as follows:

- start at some "root" of the graph--a top-level bean, or a collection thereof

- create an instance that represents a shallow copy of the root of the graph

- create an IdentityHashMap from input object to output object and use
it to map the root to its shallow copy

- iteratively, walk across the object graph and "deepen" the shallow
copy of the root as you go but, each time you encounter an object to
be copied, check your IdentityHashMap to see if you've copied this
object before--if you have, use the old copy, if you haven't, create a
new copy and add it to the map

Once you've finished visiting all nodes in the graph, you'll have a
deep copy of the root object without stack overflow and, assuming the
original object graph consumes O(N) memory, then, at the peak, you'll
be using about O(3N) during the copy, so it should fit into RAM, too.

Ian

Baptiste

unread,
Aug 20, 2008, 11:44:28 AM8/20/08
to Google Web Toolkit
You will have some others problems with serialization : PersistentSet,
Date and all temporal objects (for example, Hibernate date are
java.sql.Date, and GWT does not support it), etc...
A solution is to use BeanLib to create a clone of your objects graph
without Hibernate proxies.
In my case, I've rewrote a specific serializer/deserializer, because
BeanLib performances are not so good.


On 20 août, 17:18, "Ian Petersen" <ispet...@gmail.com> wrote:

Ian Petersen

unread,
Aug 20, 2008, 1:05:28 PM8/20/08
to Google-We...@googlegroups.com
On Wed, Aug 20, 2008 at 11:44 AM, Baptiste <baptiste...@gmail.com> wrote:
> You will have some others problems with serialization : PersistentSet,
> Date and all temporal objects (for example, Hibernate date are
> java.sql.Date, and GWT does not support it), etc...
> A solution is to use BeanLib to create a clone of your objects graph
> without Hibernate proxies.
> In my case, I've rewrote a specific serializer/deserializer, because
> BeanLib performances are not so good.

java.sql.Date and the related types in java.sql will be supported by GWT 1.5.

Ian

Baptiste

unread,
Aug 20, 2008, 1:44:54 PM8/20/08
to Google Web Toolkit
Are those types already supported (I'am using 1.5 rc1) or will be in a
futur version ?
If already supported, I'am very surprised, because I experienced
exceptions while trying to transmit it to client side of my app,
especially java.sql.Date and java.sql.Timestamp.

On 20 août, 19:05, "Ian Petersen" <ispet...@gmail.com> wrote:

Ian Petersen

unread,
Aug 20, 2008, 3:30:14 PM8/20/08
to Google-We...@googlegroups.com
On Wed, Aug 20, 2008 at 1:44 PM, Baptiste <baptiste...@gmail.com> wrote:
> Are those types already supported (I'am using 1.5 rc1) or will be in a
> futur version ?
> If already supported, I'am very surprised, because I experienced
> exceptions while trying to transmit it to client side of my app,
> especially java.sql.Date and java.sql.Timestamp.

I thought they were already supported, but I haven't used them myself.
The commit that permitted their use went in at the end of May (it was
around the time of the Goole I/O conference in San Francisco).
Perhaps you've found a bug?

Ian

noon

unread,
Aug 20, 2008, 3:34:39 PM8/20/08
to Google Web Toolkit
Hello,

Hibernate persistent collections are not supported by GWT 1.5, and it
won't probably be the case in the future.
Why GWT would have to support Hibernate specific classes ? If so, why
not OpenJPA, EclipseLink, JDO, iBatis and so on ?
In my opinion, you should definitively have a look to Hibernate4GWT,
that converts Persistent collections into basic counterparts for you
(and vice versa, when POJO is sent back from GWT to the server).

Regards
Bruno

Baptiste

unread,
Aug 20, 2008, 4:38:35 PM8/20/08
to Google Web Toolkit
Hello

I'am sure that Hibernate collections won't be supported by GWT.
It's not GWT goal to support persistence frameworks.

Of course, you can use Hibernate4GWT. But I experienced somes problems
with this solution, as explained above : performances where really
bad, due to BeanLib that break lazy loading down.
I've preferred to create my own serialization/deserialization
mechanism.

Baptiste

noon

unread,
Aug 20, 2008, 5:03:49 PM8/20/08
to Google Web Toolkit
Hi Baptiste,

As I am the author of Hibernate4GWT, I am very interested in the
experience you had.
How bad were beanlib performance ? What was the size of the data you
sent ?
Is your serialization/deserialization mechanism finished ? Are
performances better ? If so, how did you implement it ?

Bruno
Curious boy ;)

Baptiste

unread,
Aug 21, 2008, 3:59:57 AM8/21/08
to Google Web Toolkit
Hi curious boy ^^

I'm not using Hibernate4GWT, just BeanLib.
I don't use it because I don't use Hibernate, but EJB3.
To serialize/deserialize datas (ie : serialize is "kill" Hibernate
specific classes, deserialize is attach again objects to EJB3 session
and get Hibernate specific classes back), I've used BeanLib, based on
this article (sorry, it's in french) :

http://www.dotnetguru.org/temp/GWTHibernateinside.pdf

I've experienced very poor performances : BeanLib have killed lazy
loading !
Instead of replace Hibernate specific classes by null, BeanLib seams
to load datas...
My objects graph is really heavy, I can't have this solution in my
project.
So, I rewrote a little serializer/deserializer (< 300 loc / 3 days)
using introspection (of course, we can't use getters (will trigger
data loading), we must directly use fields)
My mechanism is finished. I have performance ehancement (20 times
better than BeanLib for the best one)

BUT : I'm not a BeanLib expert ! I could have made mistake while using
it that are killed performances.
I've made the choice to rewrote my own mechanism, that is more simple
to use and perfectlly fit to my app.

Curious again ? ;)

Sorry for my poor english
Baptiste

Sanj

unread,
Aug 21, 2008, 11:35:31 AM8/21/08
to Google Web Toolkit
I implemented through IdentityHashMap But after i face
StackOverFlowError.

On Aug 20, 9:19 pm, "Ian Petersen" <ispet...@gmail.com> wrote:

Sanj

unread,
Aug 21, 2008, 11:42:35 AM8/21/08
to Google Web Toolkit
Hi


I also write my service class. But i use getter and setter method for
creating a shallow copy of original Object and change PeristentBag
into ArrayList objects. For handling heavy Object Graph we use
IdentityHashMap, i know after implementing in this way there is lot of
performance issue. But atpersent i am StackOverFlow because of heavy
Object graph.

Baptiste

unread,
Aug 21, 2008, 12:23:18 PM8/21/08
to Google Web Toolkit
Hi,

What is an "heavy objects graph" for you ?
The solution with getters/setters can't be used : when you call the
getter, you call the proxy and you trigger the data loading.
A solution is to directly call fields, it's easy using introspection.
In my solution, I don't use IdentityHashMap, just a HashMap to
remember which objects I've already serialized and avoid cycles.

Baptiste

noon

unread,
Aug 22, 2008, 4:30:18 AM8/22/08
to Google Web Toolkit
Hi Baptiste,

I agree with you : using beanlib alone will eager fetch all your
associations, which is not acceptable.
That's why I developed hibernate4gwt, by customizing beanlib behavior
to (among other) prevent such behavior (Beanlib provide a
BeanPopulatable SPI to determine which associations to clone or not).

Regards
Bruno
Reply all
Reply to author
Forward
0 new messages