-->
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.  [ 3 posts ] 
Author Message
 Post subject: Best practice in distributed systems
PostPosted: Mon Jan 10, 2011 4:18 pm 
Newbie

Joined: Sat Aug 09, 2008 11:24 am
Posts: 5
Hi,

There is something that puzzles me about Hibernate when using it in a multi-tiered system, the components of which are geographically separate.

Imagine, for example, that I have the following tiers:

    - A web server running a GUI located at Location A
    - A back-end server located at Location B containing the persistence layer, exposing functionality through a web service.

The back-end server connects to a database that consists of two tables, the familiar Employee and Department (a Department having many Employees and an Employee belonging to a single Department).

Imagine now that a page is required in the GUI to display the details of a given Employee and allow his/her department to be amended. This requires two calls to the server : getEmployee and updateEmployee.

There are many, many fields in the Employee table but the GUI only requires ID, NAME, DEPT_ID.

IF the back-end server were using plain JDBC/SQL, we could envisage the following sequence of events:

    1) The GUI remotely invokes the getEmployee method.
    2) The back-end server issues a SQL command along the lines of "SELECT id, name, dept_id FROM employee WHERE id = ?" and returns the data in a response object.
    3) The user alters the employee's Department ID to be 42 and hits "submit"
    4) The GUI invokes the updateEmployee method, supplying the ID, NAME and (updated) DEPT_ID fields.
    5) The back-end server issues a SQL command along the lines of "UPDATE employee SET name =?, dept_id = ? WHERE id = ?".


During these steps we have issued a single READ to the database (to get the employee) and a single WRITE (to update the employee).

Now, imagine that we decide to use Hibernate instead of our old JDBC DAOs. As I understanding things, we now have a number of options at the back-end.

1) Not changing the interfaces between the tiers


If we keep all the interfaces the same between the tiers, we can envisage the following sequence of events:

    1) The GUI remotely invokes the getEmployee method.
    2) The back-end server loads the requested Employee using Hibernate. The relevant fields are extracted and returned in the response object used in the JDBC scenario.
    3) The user alters the employee's Department ID to be 42 and hits "submit"
    4) The GUI invokes the updateEmployee method, supplying the ID, NAME and (updated) DEPT_ID fields.
    5) The back-end server loads the Employee object using Hibernate.
    6) The back-end server loads the Department object using Hibernate and attaches it to the Employee object loaded above.
    7) The back-end server sets the Name property of the Employee object and persists the object.


Obviously, we have now gained a number of benefits from using Hibernate but we have incurred a performance hit. We have now issued three READS to the database and a single WRITE.


2) Changing the interface between tiers.


If, instead, we decide to change the interface between the tiers, we can pass detached objects between tiers, resulting in:

    1) The GUI remotely invokes the getEmployee method.
    2) The back-end server loads the requested Employee/Department using Hibernate. The Employee/Department are converted into DTOs and returned in full.
    3) The user alters the employee's Department ID to be 42 and hits "submit"
    4) The GUI invokes the updateEmployee method, supplying the entire Employee object, with the Name property updated, and the new DEPT_ID.
    5) The back-end server loads the Department object using Hibernate and attaches it to the detached Employee object supplied.
    7) The back-end server persists the object.


We have an advantage in this scenario because we can re-attach the Employee object supplied but we have still issued two READS and a single WRITE to the database. Furthermore, our network traffic has increased between the GUI and the back-end server.

So, my question is this: using Hibernate, is it possible to reduce the database access to a single READ and a single WRITE, without using SQL? Or is this simply a trade-off with the other benefits that Hibernate provides?

I appreciate that in the simple example above, the performance difference is negligible but I have seen situations where this has quickly become a problem.

I hope the example makes sense. I'd be interested to know what the consensus is on best practice.

Thanks in advance,

Simon


Top
 Profile  
 
 Post subject: Re: Best practice in distributed systems
PostPosted: Wed Jan 12, 2011 6:48 am 
Hibernate Team
Hibernate Team

Joined: Fri Oct 05, 2007 4:47 pm
Posts: 2536
Location: Third rock from the Sun
First, you should consider if the original operation you're doing with plain JDBC is correct. What happens if someone else in the meantime updates one of those entities? Are you locking the table/row between the user interaction? Obviously for scalability you shouldn't start a transaction which could potentially last the time of your user's coffee break or his next meeting.
Hibernate is reloading the entity to perform all needed consistency checks.

that said, the answer is still yes: look into extended persistence context in the reference documentation.

_________________
Sanne
http://in.relation.to/


Top
 Profile  
 
 Post subject: Re: Best practice in distributed systems
PostPosted: Wed Jan 12, 2011 2:30 pm 
Newbie

Joined: Sat Aug 09, 2008 11:24 am
Posts: 5
Thanks for replying.

You are quite right and I take your point. That is something that would have to be considered in a real application, in which case my JDBC example would not be a valid description of the number of calls to the database.

It was more the reloading of the referenced objects that puzzled me (i.e. loading the Department merely to attach it to the Emloyee).

However, since posting the original message, I have discovered that the answer to the problem is clearly explained in my Java Persistence with Hibernate book, using a very similar example to the one I posted.

The answer would be to use the load method (rather than get) AND configure the @AccessType of the Department.id property correctly. This would enable me to load a proxy that wraps the ID, sufficient for persisting the Employee, without touching the database.

I knew it would be something that I had missed. :-)


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 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.