-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 17 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: using indigo (wcf) to send domain objects.
PostPosted: Mon Jan 23, 2006 5:26 am 
Senior
Senior

Joined: Thu Aug 25, 2005 3:35 am
Posts: 160
Hi all,

I know this might not be extremely nHibernate specific, but is anyone already using indigo to send and receive domainobjects ?

I have a parent-child objectgraph, with a bi-directional relation. I can only send this over the wire using: [XmlSerializerFormat(Style=OperationFormatStyle.Rpc, Use=OperationFormatUse.Encoded)]

Obviously I do not want to using encoding or rpc style.
Does anyone have a solution for the circular reference problem?

Thanks,
Ruurd


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 23, 2006 6:04 am 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
I think You should not sent Domain objects over wire (like results of web service methods):

1. You do not want the methods to be visible in client side. The emthods are probably using some server specific code, the every method execution must end in callback to server. And, if You do not want allow callbacks,
2. All sub-objects should be serialized, as You do not want to trigger callback by accessing them. This might mean that the whole object graph is sent back inside one result message. Depending on Your database size, this might be several gigabytes (!)

So, if You need to pass data over wire, better create separate data-carrier classes to be used. I would opt in creating some custom code generator (and extending metadata with custom attributes to avoid need to change generated code)

For coping data between carrier and domain object, it is probably possible to create some simple general code using reflection. Or You might use code generation...

Gert


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 23, 2006 8:18 am 
Senior
Senior

Joined: Thu Aug 25, 2005 3:35 am
Posts: 160
Actually, sending domain objects over the wire is exactly what is recommended in the hibernate in action book.
If I create DTO objects, that is just another class. My domain objects are 'dumb' and actually are the kind of objects you might think of as dto.


However, your data-carrier classes would not at all alleviate my problems. I would still have a datacarrier object with a reference to another data carrier. There would still be a circular reference. And indigo would still crash on it!


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 23, 2006 9:24 am 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
TheShark wrote:
Actually, sending domain objects over the wire is exactly what is recommended in the hibernate in action book.
If I create DTO objects, that is just another class. My domain objects are 'dumb' and actually are the kind of objects you might think of as dto.


If You send domain objects opver wire with MarshalByValue semantic, the how could You introduce breaks in graph? Sending entire database is not good choise, I'm afraid...

TheShark wrote:
However, your data-carrier classes would not at all alleviate my problems. I would still have a datacarrier object with a reference to another data carrier. There would still be a circular reference. And indigo would still crash on it!


You could convert object-refernces to ObjectId refernces (so that circles would be broken) and reconstruct graph at client side.

Gert


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 23, 2006 9:51 am 
Senior
Senior

Joined: Thu Aug 25, 2005 3:35 am
Posts: 160
gert wrote:
If You send domain objects opver wire with MarshalByValue semantic, the how could You introduce breaks in graph? Sending entire database is not good choise, I'm afraid...

You could convert object-refernces to ObjectId refernces (so that circles would be broken) and reconstruct graph at client side.

Gert


I don't think we're on the same page here ;-)
I'm not sending the entire database at all. I'm getting an objectgraph, disconnecting from session, and sending that small object graph.

Also, as I state in my topic name, I'm using Indigo. The new xmlformatter actually creates ID's and REFerences.
So my objectgraph is a thing of beauty ;-)

You should now worry about me sending the complete database.. i'm not.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 23, 2006 10:44 am 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
TheShark wrote:
I don't think we're on the same page here ;-)
I'm not sending the entire database at all. I'm getting an objectgraph, disconnecting from session, and sending that small object graph.


Maybe I'm missing something, but I see three possibilities:

1. The objects are sent using MarshalByReference semantic, which causes possible callbacks on property access.
2. When MarshalByValue semantic is used, all objects referenced direclty or indireclty by given object are serialized. This _migh_ cause entire database to be sent - in case when most objects are related to each-other (introducing a "Owner" property causes owner to be written, which in turn causes all child to be written... And so on).
3. When MarshalByValue semantic is used, some references are so-called "breaks", i.e. the referenced object is not serialized. How to write such info into domain model and still keep it usable is mystery for me. (And when writing domain model I do not want to think about remoting issues).

BTW, this is probaly answer to Your question: change some references so that the referenced object is not serialized: I'm not very familiar with fine-tuning serialization, but adding NonSerializedAttribute or XmlIgnoreAttribuet to the member (or some Indigo specific attribute) should help. Or use ObjectId instead of Object property. (And have some code on client siode to handle those breaks...)

TheShark wrote:
Also, as I state in my topic name, I'm using Indigo. The new xmlformatter actually creates ID's and REFerences.
So my objectgraph is a thing of beauty ;-)


I did think that the Indigo is only a new sexy way to write and use different remoting protocols, not a new protocol itself... Maybe I should download and install it, to see what animal we are talking about....

TheShark wrote:
You should now worry about me sending the complete database.. i'm not.

I'm not worried - it is not data from my database :-P


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 23, 2006 11:03 am 
Senior
Senior

Joined: Thu Aug 25, 2005 3:35 am
Posts: 160
gert wrote:
Maybe I'm missing something, but I see three possibilities:

1. The objects are sent using MarshalByReference semantic, which causes possible callbacks on property access.
2. When MarshalByValue semantic is used, all objects referenced direclty or indireclty by given object are serialized. This _migh_ cause entire database to be sent - in case when most objects are related to each-other (introducing a "Owner" property causes owner to be written, which in turn causes all child to be written... And so on).
3. When MarshalByValue semantic is used, some references are so-called "breaks", i.e. the referenced object is not serialized. How to write such info into domain model and still keep it usable is mystery for me. (And when writing domain model I do not want to think about remoting issues).


Since it's xml serialization, it is marshalled by value.
point 2: this might indeed cause the entire database to be sent, but only if my object graph encompassed the entire database.
In other words, the serialization of objects that are live, will not cause nhibernate to go to the database.
point 3: I do not have to write these things into my domain model, the xmlformatter of indigo correctly identifies them.
For instance, i have a 'book' object with a collection of 'pages'. Each page has a reference back to the book object, then the page object would not serialize the complete book object, but just write out: <z-REF = 1 /> where the book was given <z-ID = 1 />
This all works great.

gert wrote:
BTW, this is probaly answer to Your question: change some references so that the referenced object is not serialized: I'm not very familiar with fine-tuning serialization, but adding NonSerializedAttribute or XmlIgnoreAttribuet to the member (or some Indigo specific attribute) should help. Or use ObjectId instead of Object property. (And have some code on client siode to handle those breaks...)


Then I would lose references.
Since the produced xml uses objectid's, it seems to be a bug that it can't send it over the wire properly.

gert wrote:
I did think that the Indigo is only a new sexy way to write and use different remoting protocols, not a new protocol itself... Maybe I should download and install it, to see what animal we are talking about....


hehe, well, it does introduce some new subtleties.

gert wrote:
I'm not worried - it is not data from my database :-P


hehe, lol!


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 23, 2006 11:34 am 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
TheShark wrote:
Since it's xml serialization, it is marshalled by value.
point 2: this might indeed cause the entire database to be sent, but only if my object graph encompassed the entire database.
In other words, the serialization of objects that are live, will not cause nhibernate to go to the database.

I do not understand, how can the lifeness of objects affect the serialization? The referenced object is either alive or it is a proxy which implements lazy-loading, i.e. fetches data from database as soon as someone (the serialization logic) touches something that needs to be fetched. So, as much as seriualization is concerned, all objects are acting "alive".

Quote:
point 3: I do not have to write these things into my domain model, the xmlformatter of indigo correctly identifies them.
For instance, i have a 'book' object with a collection of 'pages'. Each page has a reference back to the book object, then the page object would not serialize the complete book object, but just write out: <z-REF = 1 /> where the book was given <z-ID = 1 />
This all works great.

Maybe You should describe how Your code is failing... (like compilation/runtime error)

[/quote]


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 23, 2006 1:44 pm 
Expert
Expert

Joined: Fri Oct 28, 2005 5:38 pm
Posts: 390
Location: Cedarburg, WI
We've been serializing object graphs with bidirectional parent/child references since .NET 1.0. We had to write methods like RepairBidirectionalReferences() that got called after deserializing. Each object had to know how to repair itself, by knowing explicitly about possible relationships to its parent and children.

It's been a long time since I touched that code, but I think we set it up so that the references on the child back to the parent would not be serialized. Then, after deserialization, the RepairBidirectionalReferences() method on the parent would loop through its children and set the child's "Parent" property to itself.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 23, 2006 3:17 pm 
Senior
Senior

Joined: Thu Aug 25, 2005 3:35 am
Posts: 160
Nels: okay, that's good to know. With binary serialization I never had that problem. Also, I'm hoping not to have to go through this. ;-)

gert wrote:
I do not understand, how can the lifeness of objects affect the serialization? The referenced object is either alive or it is a proxy which implements lazy-loading, i.e. fetches data from database as soon as someone (the serialization logic) touches something that needs to be fetched. So, as much as seriualization is concerned, all objects are acting "alive".


What is 'alive'? It is the fact that nhibernate is going to step in as soon as i hit something that was not there before?? Well, nhibernate does that by giving a 'nhibernate.bag' or list as the collection and letting the developer talk to the collection as an iList. By serializing as an iList, it should not come back as an nhibernate.bag. I don't even have nhibernate.dll's on my client.

Quote:
Maybe You should describe how Your code is failing... (like compilation/runtime error)


Good idea: (following classes were made to pinpoint my problem).
I have a class 'Book' which has a collection 'Pages'. Each 'Page' object has a property 'motherBook': the book it belongs to.
When I serialize myself, the xmlformatter creates this beauty:
<?xml version="1.0" encoding="utf-8" ?>
- <Book xmlns:i="http://www.w3.org/2001/XMLSchema-instance" z:Id="1" z:ClrType="ConsoleApplication1.Book" z:ClrAssembly="ConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" xmlns="http://schemas.datacontract.org/2004/07/ConsoleApplication1">
<amountPages>200</amountPages>
- <paginas z:Id="2">
- <_items z:Id="3" z:Size="1">
- <Page z:Id="4">
<amountWords>3000</amountWords>
<motherBook z:Ref="1" i:nil="true" />
</Page>
</_items>
<_size>1</_size>
<_version>1</_version>
</paginas>
</Book>

I can also deserialize this...
Do you see the 'z-Id' that is being generated and the z:ref ?

However, when I use a netTcp binding as my endpoint and have the above class 'Book' as a returnvalue in an indigo server/client application, the client bombs with an unexpected fault/exception. There is the mention of the stream not being okay, but absolutely nothing usefull.

If I switch to rpc-style communication, it works.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 23, 2006 4:05 pm 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
TheShark wrote:
What is 'alive'?

Exactly my question... But, as You introduced this term, maybe You should explain <g>

TheShark wrote:
It is the fact that nhibernate is going to step in as soon as i hit something that was not there before?? Well, nhibernate does that by giving a 'nhibernate.bag' or list as the collection and letting the developer talk to the collection as an iList.

AFAIK the lazy loading is not limited to lists. It steps in for usual many-to-one association. I.e. when loading class A whihc has reference to class B, only proxy of B is created. And data is fetched from database when somthing uses properties of B proxy.

TheShark wrote:
However, when I use a netTcp binding as my endpoint and have the above class 'Book' as a returnvalue in an indigo server/client application, the client bombs with an unexpected fault/exception. There is the mention of the stream not being okay, but absolutely nothing usefull.

Well, there are several debugging technicues to find out the actual exception:

1. If the server is SOAP server, use internet explorer to view actual message returned. If You can not use IE, try using Visual Studio to get hands on the actual message returned from server. It might contain some exception description.
2. Use debugger whith "Break when (managed) exception thrown" set to debug server-side code. Then You can see what is actual exception generated at server side. You can also isnpect the stack trace to see what and where is used. (sometimes having a look at "locals" and "autos" views when the stack is pointed at in system code (disassembly) is very insightful).


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 23, 2006 4:38 pm 
Senior
Senior

Joined: Thu Aug 25, 2005 3:35 am
Posts: 160
Quote:
Exactly my question... But, as You introduced this term, maybe You should explain <g>


I meant attached objects as in attached to a session. Requesting a property at that moment would indeed trigger the proxy to go to the database. Serialization does not, for all I know, but it's worth testing out more seriously.

Quote:
1. If the server is SOAP server, use internet explorer to view actual message returned. If You can not use IE, try using Visual Studio to get hands on the actual message returned from server. It might contain some exception description.


It's an indigo server ;-)

Quote:
2. Use debugger whith "Break when (managed) exception thrown" set to debug server-side code. Then You can see what is actual exception generated at server side. You can also isnpect the stack trace to see what and where is used. (sometimes having a look at "locals" and "autos" views when the stack is pointed at in system code (disassembly) is very insightful).


I'm afraid I've done all that. It does not break on the server.

However, what I will try to do is log all the messages more exactly, and see what exactly is sent to the client. I'll write a message if that gives something.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 24, 2006 2:17 am 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
TheShark wrote:
I meant attached objects as in attached to a session. Requesting a property at that moment would indeed trigger the proxy to go to the database. Serialization does not, for all I know, but it's worth testing out more seriously.


From help: "XML serialization serializes only the public fields and property values of an object into an XML stream." So, I see no reason why it should not trigger database access. AFAIK, binary serialization uses fields whith any visibility...

TheShark wrote:
Quote:
1. If the server is SOAP server, use internet explorer to view actual message returned. If You can not use IE, try using Visual Studio to get hands on the actual message returned from server. It might contain some exception description.


It's an indigo server ;-)


Can't Indigo server play a role of SOAP server?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 24, 2006 4:09 am 
Senior
Senior

Joined: Thu Aug 25, 2005 3:35 am
Posts: 160
Quote:
From help: "XML serialization serializes only the public fields and property values of an object into an XML stream." So, I see no reason why it should not trigger database access. AFAIK, binary serialization uses fields whith any visibility...


I'm not using xml serialization, but xmlformatter. it's a new class, used by the indigo serialization engine. It allows you to decorate private fields with a [datamember] attribute, to have it serialized.

Quote:
Can't Indigo server play a role of SOAP server?


yes it can. but i'm using the tcp binding.. i'll look into the messages..

However, I've raised the whole issue with microsoft. They got back to me stating that they are moving _away_ from object graphs because there is not an interoperable way of doing this in xml (something java would understand as well I guess, out of the box). To get the effect that I want, I need to enable a few switches (the ones I mentioned in my start post), that will trigger an indigo rpc style of serialization.
So they have a few suggestions on how to approach the problem, that I'm going to study.. I think I'll stick with the rpc method for now ;-()


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 24, 2006 5:53 am 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
TheShark wrote:
So they have a few suggestions on how to approach the problem, that I'm going to study.. I think I'll stick with the rpc method for now ;-()


I start to think that You have been correct in most statements (and this in turn means that I was indeed on another page :( )

The only possible useful information I can add: the article http://msdn.microsoft.com/msdnmag/issues/06/02/WindowsCommunicationFoundation/default.aspx mentions message logging utility at the end...


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 17 posts ]  Go to page 1, 2  Next

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.