wood burning stoves 2.0*
The moose likes Object Relational Mapping and the fly likes Timestamping in Hibernate Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Databases » Object Relational Mapping
Bookmark "Timestamping in Hibernate" Watch "Timestamping in Hibernate" New topic
Author

Timestamping in Hibernate

Marc Heruela
Ranch Hand

Joined: Jul 23, 2009
Posts: 38
Hello guys,

Iv got some delimma on how to check timestamping using Hibernate. Here's the situation:

Iv got a table: USER with columns [username, password, lastModified, lastModifiedBy]

*Note that lastModified is timestamp (sql data type) and the default value is CURRENT_TIMESTAMP.

Pretty much I let sql do the updating of USER.lastModified field, by setting lastModified into null when I save an instance of User class.

My problem is this, I am having a hard time designing, on how to check the timestamp first before a certain USER record is updated/saved.

When a user tries to update the USER_1 record, then before saving, my system should first query the database first and get the current lastModified field of USER_1 record.

If the timestamps of USER_1 (stored in the User instance) and the timestamp retrieved from the database does not much, update on USER_1 must not be allowed.

an error saying: "ERROR: SOMEONE ELSE HAS UPDATED THIS RECORD, PLEASE GO BACK TO PREVIOUS PAGE AND CLICK THE SAME USER TO RELOAD THE NEW DATA".

Here's my code: (I am using Hibernate and spring-orm-support for Hibernate)

Model:



My design has UniversalDao that handles the most basic CRUD functionality, including save. All you have to do is passed the object to be saved.

Here's a snippet:





In my UniversalDaoHibernate above, before I save the Object o (in this case instance of User class)
I still have to check the timestamp fields if they match what is on the database. Now the problem is,
not all table in my database has a timestamp field, so not all table need to be checked. How would be
the most efficient and best way to implement this. My plan is to check if Object o has a getLastModified() method
which would tell me that it has a timestamp. But since if o.getClass() will return the class Object, then for sure
it doesn't have a getLastModified() method (or am I mistaken???). I want to retain my current design, I dont want to create a save() method
for all my hibernate models. Would that be possible?

Please advise.

Thanks
-marckun


-marckun
Paul Sturrock
Bartender

Joined: Apr 14, 2004
Posts: 10336

If you are using Hibernate could you not just use its built in versioning capabilities? If your mapped object does not have a version field a save will just overwrite without checking.


JavaRanch FAQ HowToAskQuestionsOnJavaRanch
Marc Heruela
Ranch Hand

Joined: Jul 23, 2009
Posts: 38
Paul Sturrock wrote:If you are using Hibernate could you not just use its built in versioning capabilities? If your mapped object does not have a version field a save will just overwrite without checking.


Ohh. Does he have one? Do you have some tutorial on this?? The very starter tutorial on timestamping?

Thanks a lot.

-marckun
Marc Heruela
Ranch Hand

Joined: Jul 23, 2009
Posts: 38
Hello guys,

I would like to seek your expert advise on how to properly design my system. this is my first time setting up the hibernate environment for a project so if you dont mind please go easy on me.

The system that I'm gonna do, involve intensive monetary transactions, that said, i need it to be 100% secure. Here is the scenario:

Customer A, withdraws money from the system by filling in a withdraw form and submits the form for validation.
When the transaction is on the validation stage (during this time, the accounting department of the system is validating the information sent, like account number, etc etc),
Customer A can cancel his request (the withdraw transaction) by clicking a Cancel button. At the same time, the accounting department can set the status of the
transaction to transferring when the validation is completed. and during this stage(transferring), the actual withdraw transaction is done.

The problem is, when the user first fills in the withdraw form, his account balance was subtracted already, when he cancels it, the account balance is restored. also, when the withdraw request is set to transferring, the account balance wont be subracted anymore (since it has been subracted when the customer first fills in the form). the trouble is, when the user cancels the account (meaning the balance is restored), and the accounting department has set it transferring, the transferring now is in progress, and the account balance of the customer wont change (meaning, the balance was restored to the original unsubtracted amount, which implies the SYSTEM IS GIVING MONEY TO THE CUSTOMER).

What I would like to ask is this:

Is it wise for me to do this:, when the user loads the record on the screen, the record will be locked. and i will also apply versioning, so that when the record has been modified the version is changed, and during this time the lock is released, so any modification (by another user) would check the version of the record.

Or would it be better to gain the lock when the "update" of the record is on progress. like on load of the record, there is no lock, and on submit of form (thus, update query will be invoked), the locked for that record will be gained, and any more access will be rejected. once the transaction (update) is complete, version of will change, and any more transaction for the same record will ask to validate the version of the record they are updating.

I am just preventing any problem for concurrent users (between the Customer and Accounting deparment), though this is an isolated/rare case, which will need a very incredible coincidence for this to happen, but none the less; this is a possibility..

Thank you so much guys.

I would also like to ask how to configure the record locking in hibernate. do we configure it in hibernate.cfg.xml file, in the applicationContext.xml???

I am using Hibernate annotations with spring-orm support and MySQL 5.

please advise.

tenkyou:
-marckun
Paul Sturrock
Bartender

Joined: Apr 14, 2004
Posts: 10336

Marc Heruela wrote:
Paul Sturrock wrote:If you are using Hibernate could you not just use its built in versioning capabilities? If your mapped object does not have a version field a save will just overwrite without checking.


Ohh. Does he have one? Do you have some tutorial on this?? The very starter tutorial on timestamping?

Thanks a lot.

-marckun


Timestamping and versioning are mentioned here. I don;t have a tutorial link I'm afraid, but both are pretty straight forward. See how you go with that link.
Paul Sturrock
Bartender

Joined: Apr 14, 2004
Posts: 10336


the trouble is, when the user cancels the account (meaning the balance is restored), and the accounting department has set it transferring, the transferring now is in progress, and the account balance of the customer wont change (meaning, the balance was restored to the original unsubtracted amount, which implies the SYSTEM IS GIVING MONEY TO THE CUSTOMER).

This sounds a little like the customer should not be allowed to cancel a request that has entered the transfering state? So could you not just change your business logic to prevent this?


Is it wise for me to do this:, when the user loads the record on the screen, the record will be locked.

Normally, pesimistic locking is frowned on, because it puts a bottleneck in the system. However given this is a specific user managing their own balance I'd say this is one of the few occasions where pesimistic locking may a good idea. If you go for this approach you no longer need optimistic locking (i.e. versioning) too. I suppose you have to consider how often something else other than the user changes the balance.


Or would it be better to gain the lock when the "update" of the record is on progress.

Yes. You don't want to indescimitately allow pesimistic locking. What I'd do is have an update screen that will reselect the data using a lock so you only get the lock when you are anticipating an update.
Marc Heruela
Ranch Hand

Joined: Jul 23, 2009
Posts: 38
Paul Sturrock wrote:

the trouble is, when the user cancels the account (meaning the balance is restored), and the accounting department has set it transferring, the transferring now is in progress, and the account balance of the customer wont change (meaning, the balance was restored to the original unsubtracted amount, which implies the SYSTEM IS GIVING MONEY TO THE CUSTOMER).

This sounds a little like the customer should not be allowed to cancel a request that has entered the transfering state? So could you not just change your business logic to prevent this?


Is it wise for me to do this:, when the user loads the record on the screen, the record will be locked.

Normally, pesimistic locking is frowned on, because it puts a bottleneck in the system. However given this is a specific user managing their own balance I'd say this is one of the few occasions where pesimistic locking may a good idea. If you go for this approach you no longer need optimistic locking (i.e. versioning) too. I suppose you have to consider how often something else other than the user changes the balance.


Or would it be better to gain the lock when the "update" of the record is on progress.

Yes. You don't want to indescimitately allow pesimistic locking. What I'd do is have an update screen that will reselect the data using a lock so you only get the lock when you are anticipating an update.


i really really like your response. you hit what i really want to know.. thanks

but there is this one thing that has been bugging me for ages regarding this whole database record locking stuff..

just a question though, (im sorry if this sounds really stupid, but cant help it, im a rookie when it comes to this),

when two users accessed the same record at the same time (no matter which approach, pesimistic or optimistic locking),

when a record is lock by the first user and the first user changes or made some modifications over some data, and commits it,

the lock is released right??? when the second user waited patiently for the first user to commit, and to release the lock

can he save his changes??? assuming he didnt refresh the page to reload the updated data/record made by the first user.

im just curious what ought to be the default behavior when this happen.... yes lock has been granted to only one user when

one user is updating the data, but when he released the lock, can the next user just save his changes (assuming both users

loads their data at the same time)???

assuming there is no versioning..

thank you very much... iv been trying to search the net for answers.. i cant seem to find satisfaction with what they are telling.. iv tried doing it, i have very normal table... and stage two users accessing (loading the data on the screen) at the same time.. apply different modifications to both, and click save at a different time.. the behavior is that the last user to save overrides the first changes made by the first...

-marckun

ps: i asked this because people told me that i should NOT worry about this stuff because hibernate is handling this issues by default..
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: Timestamping in Hibernate