Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Object getting wrong time stamp from Hibernate saved to database

I am new to Hibernate and working on a web project that uses it.

I have an object called area that has a date object(java.sql.Timestamp) attribute modifiedDate. When I create a new object modifieDate is null and after send it down to getHibernateTemplate().saveOrUpdate(area); in my own class that extends org.springframework.orm.hibernate3.support.HibernateDaoSupport it is set with current timestamp and saved in the database. In the database it is saved as a datetime.

My problem is most of the time the object is updated with a Date that is 1 millisecond off compared to what it is saved as in the database, this leads to this exception if anything is attempted updated without reloading the page:

an org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)

There are no problems with the correct date when getting the object from database subsequent, it is only at creation it gets the wrong value.

Is there a way to get the correct modifiedDate at SaveOrUpdate?

Incase it is needed the mapping uses <timestamp name="modifiedDate" column="ModifiedDate"/> and all test are run on localhost with everything running on the same machine.

I already have a work around, by calling getHibernateTemplate().refresh(area); right after the saveOrUpdate I get the right timestamp, but I would still like to know if there is a way to get the correct modifiedDate at saveOrUpdate.

like image 943
Blem Avatar asked Aug 09 '12 08:08

Blem


1 Answers

My theory:

What's happening is that you're using a less precise data type on the database side than on the Java side, so the values you persist to the DB are losing precision (or rounded somehow, see below) during generation of the DB-specific SQL. Here's how to tell for sure:

  1. Remember, Hibernate works by generating SQL statements that are executed in your database. In order to diagnose issues with Hibernate mappings like this, you will need to see the SQL being executed in order to know precisely what's going on.

  2. Turn on the 'show SQL' setting for Hibernate. This will cause Hibernate to dump the raw SQL being executed on the database.

  3. Examine the logs from your tests. It will help to implement toString on your class and log the value to compare against the SQL hibernate generates for an INSERT. Do the values in the SQL statements match the value of the Java timestamp field?

You should check the precision settings for your database's DATETIME type. For example, on SQL Server, DATETIME implements millisecond rounding (see 'accuracy' field) that effectively causes loss of precision for millisecond values. You will want to change the Java type your column is mapped to or change the type of the column in the database, depending on your precision needs.

like image 160
Paul Morie Avatar answered Nov 15 '22 16:11

Paul Morie