-->
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.  [ 8 posts ] 
Author Message
 Post subject: NHibernate in a remoting / WCF scenario
PostPosted: Mon Jul 28, 2008 4:49 pm 
Regular
Regular

Joined: Mon Aug 29, 2005 3:07 pm
Posts: 77
I am thinking on how I could use NHibernate in a remoting scenario (using .NET remoting, WCF, webservices, whatever ...... ), but I can already see some problems which I will likely encounter on my path.

This is how I see the big picture of the application:

Image

Let me explain it in short:
The client application (a rich Windows client for instance) communicates via some kind of technique, be it WCF or the old .NET remoting, with the Service Layer.
This means that the client application calls a (remote) method on the Service Layer to retrieve a Customer for instance. The client can make some changes to that object and later, the client can call the remote 'SaveCustomer' method so that the Service Layer can persist the changes back to the datastore.
In order to do this, the Service Layer uses a Repository that uses NHibernate to retrieve or persist objects.
Note that the Client Application and the Remote service layer use the same Domain Entities. This means that the domain classes need to be [Serializable].

The problem that I will be facing is this:
- Since (N)Hibernate uses its ISession as a UnitOfWork, which keeps track of the objects that have been created, deleted, inserted, the Client Application doesn't know whether it is necessary to perform a remote call to save the entity or not.
(The client application doesn't know anything of some thing called an 'NHibernate Session', and my business object (entity) has no state tracking as well. (In other words: my entity itself doesn't know whether it has been created, changed or deleted).

- The remote method which will save my entity, will use another ISession then the method that has retrieved it. (Remote methods should be stateless, since multiple callers can call the same method. Client x should not know anything of client Y).
The fact that the 'SaveCustomer' method will use another ISession, means that it is possible that NHibernate will perform unnecessary UPDATE statements. This could be problematic if you use an AuditInterceptor, since this Interceptor will update the LastUpdated, Version, etc... columns in the DB, while this was not necessary. In other words: this leads to wrong information in the database.

How could these problems be tackled:
- For the first problem, you could implement some kind of 'state tracking' in your entities, and add a property which tells you whether the entity has modified , etc...

- Implementing state-tracking in your domain entities may also solve the 2nd problem; in your repository you can check whether you've to Update or Save (for new entities) your entity. However, I don't know yet how this will behave in situations where an entity contains a collection of other entities ...


I'd like to know from other people how they have tackled these kind of problems ? Did you implement some kind of state tracking in your business entities ?
Or, did you choose not to expose your business entities to the client application, and use Data Transfer Objects instead ? If so, how did you map these DTO's to your business classes ?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 29, 2008 3:41 am 
Newbie

Joined: Mon Jul 28, 2008 10:16 am
Posts: 4
Have you had a look at Billy Mccafferty's article for Nhibernate best practices? He covers several of your points and addresses some of the problems faced.

[url]http://www.codeproject.com/KB/architecture/NHibernateBestPractices.aspx
[/url]

Regards,

Paul[/url]


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 29, 2008 5:16 pm 
Regular
Regular

Joined: Mon Aug 29, 2005 3:07 pm
Posts: 77
Thx for your reply :)

I know about this article by Billy McCafferty, but I don't think he touches the problems I outlined here ? This article is not about distributed architectures, but rather about using NHibernate in an ASP.NET app ?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 30, 2008 9:41 pm 
Newbie

Joined: Wed Jul 30, 2008 8:47 pm
Posts: 11
Location: Merlbourne, Australia
Also very interested in Best Practices in these situations


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 31, 2008 1:10 am 
Newbie

Joined: Wed Jul 30, 2008 2:35 pm
Posts: 3
I never expose my domain objects directly to client services -- in my opinion this builds a direct field-level dependency that basically discourages you from ever changing any fundamentals of your domain representation. Refactoring and redesign should be easy and desirable as conditions change and new functionally is needed, and these things might become downright impossible if your clients are intimately linked to the precise implementation of the way you do things on the server side. So I use DTO objects compulsively which may or may not have very similarly named or typed fields as my domain objects, but still afford me the flexibility to expose domain-specific ideas in an end-result form rather than how I choose to represent those ideas in back-end processes.

I'm not sure I'm understanding your question exactly, though -- why would the client call the save function if it wasn't sure whether or not calling save was necessary? Also, doesn't the presence or absence of an an id generally tell you whether or not something is an update or an insert (assuming a surrogate key)? If that's the case, and the repository is the one that generates the key (or the database), then I would think the repository should know right away whether or not it's a new or existing object. Or is this a question of efficiency where perhaps the client sent in a version of an object that technically had all the same values as the persisted version?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 31, 2008 4:09 am 
Regular
Regular

Joined: Mon Aug 29, 2005 3:07 pm
Posts: 77
frogurt wrote:
So I use DTO objects compulsively which may or may not have very similarly named or typed fields as my domain objects, but still afford me the flexibility to expose domain-specific ideas in an end-result form rather than how I choose to represent those ideas in back-end processes.

How do you translate your domain objects to your DTO's ? What techniques do you use ? I've read something about NHibernate projections, which should make it easy to do this mapping ?
Can you elaborate a bit more on how you map to and from your DTO's ?

Quote:
I'm not sure I'm understanding your question exactly, though -- why would the client call the save function if it wasn't sure whether or not calling save was necessary?

Since the objects don't include any state-tracking (in NHibernate, the ISession does this, and the session is not available at the client), my client doesn't know whether the object has changed or not. (Unless I implement this functionality in my objects so that the client can ask if the object has changed or not).

Quote:
Also, doesn't the presence or absence of an an id generally tell you whether or not something is an update or an insert (assuming a surrogate key)?
Not in all cases. Suppose the user has requested an object, and wants to edit it. However, he / she closes the form without changing something to the object.

Quote:
Or is this a question of efficiency where perhaps the client sent in a version of an object that technically had all the same values as the persisted version?
Indeed. In such cases, the client shouldn't even make the remote call.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 04, 2008 8:39 pm 
Newbie

Joined: Wed Jun 21, 2006 2:45 pm
Posts: 16
DTO is always brought up, but rarely have I see good example on the best practices to implementing them outside of some sort of mapping technique. And even so, how does it handle retrieving by ID's, etc...

ie. if I have a semi large domain object graph (ie. Customer with Addresses, Invoices, Billings, etc...) - mapping that to and from DTO's would worry me. ie. Do I repopulate an entire Customer from a CustomerDTO object sent to the server?

ie.

Customer.Name = CustomerDTO.Name;
...

picture many properties and collections of a customer....


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 05, 2008 8:48 am 
Regular
Regular

Joined: Mon Aug 29, 2005 3:07 pm
Posts: 77
SteveG wrote:
DTO is always brought up, but rarely have I see good example on the best practices to implementing them outside of some sort of mapping technique. And even so, how does it handle retrieving by ID's, etc...

ie. if I have a semi large domain object graph (ie. Customer with Addresses, Invoices, Billings, etc...) - mapping that to and from DTO's would worry me. ie. Do I repopulate an entire Customer from a CustomerDTO object sent to the server?

ie.

Customer.Name = CustomerDTO.Name;
...

picture many properties and collections of a customer....
This is also one of my worries regarding DTO's.
As I've stated earlier, I've read something about NHibernate projections, but I need more information about this. I also need to play with it.
If anybody has some fine resources about this topic, plz let me know.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 posts ] 

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.