-->
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: Timestamp and StaleObjectStateException
PostPosted: Wed Feb 23, 2005 11:10 am 
Beginner
Beginner

Joined: Tue Nov 02, 2004 1:34 pm
Posts: 45
I've set a timestamp in my hbm.xml, but I'm not getting the exception when two users change the same data. I'm getting "last saved wins". Is there more than setting the <timestamp> in the hbm.xml that I need to do? Do I need to set the session.lock?

Here's the relevant part of my hbm.xml

Code:
<timestamp name="lastModDate" column="LAST_MOD_DATE" />


Here's my method for persisting:

Code:
   public String makePersistent(Metric metric) throws InfrastructureException
   {
      try {
         log.info("persisting lastModDate: " + metric.getLastModDate().toString());
         HibernateUtil.getSession().saveOrUpdate(metric);
         HibernateUtil.getSession().flush();
      } catch (HibernateException ex) {
         throw new InfrastructureException(ex);
      } catch (Exception e) {
         throw new InfrastructureException(e);
      }
      return metric.getMetricId().toString();
   }


In my action class that processes the form, I've traced the values of lastModDate. I have confirmed that the value in the database is different than the value in the form....that I've set my metric.lastModDate to the value in the form (which differs from the database) and it persists with no exception thrown.

Relevant part of the trace:

Code:
INFO  - [MetricCRUDAction.getMetric] lastModDate from database: 2005-02-23 08:41:01.0
INFO  - [MetricCRUDAction.getMetric] lastModDate from form: 2005-02-23 08:34:15.0
INFO  - [MetricCRUDAction.getMetric] metric.lastModDate set to: 2005-02-23 08:34:15.0
INFO  - [MetricCRUDAction.processForm] after BeanUtils.copy lastModDate: 2005-02-23 08:34:15.0
INFO  - [MetricCRUDAction.processForm] right before makePersistent lastModDate: 2005-02-23 08:34:15.0


I can see in the sql generated that Hibernate has added the "where lastModDate =" -- which indicates to me that the versioning is attempting to work

Code:
where METRIC_ID=? and LAST_MOD_DATE=?


I have read chapter 5 of the Hibernate in Action book...and I can't see where I'm missing a step. The value is stored in the database so it's not merely a failure to capture an exception.

Lee

----------------------------------------------------------------------------
Hibernate version: 2.17

Mapping documents:
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
                            "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
                            "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >

<!-- DO NOT EDIT: This is a generated file that is synchronized -->
<!-- by MyEclipse Hibernate tool integration.                   -->
<!-- Created Fri Oct 22 15:09:02 CDT 2004                         -->
<hibernate-mapping package="com.sbc.netrics.struts.database">

    <class name="Metric" table="METRIC">
        <id name="metricId" column="METRIC_ID" type="java.lang.Long">
         <generator class="sequence">
                <param name="sequence">METRIC_SEQ</param>
           </generator>       
        </id>
        <timestamp name="lastModDate" column="LAST_MOD_DATE" />

        <property name="metricNumber" column="METRIC_NUMBER" type="java.lang.String" />
        <property name="metricName" column="METRIC_NAME" type="java.lang.String"  not-null="true" />
        <property name="metricDescription" column="METRIC_DESCRIPTION" type="java.lang.String" />
        <property name="dataType" column="DATA_TYPE" type="java.lang.String" />
        <property name="length" column="LENGTH" type="java.lang.Long" />
        <property name="decimals" column="DECIMALS" type="java.lang.Short" />
        <property name="columnName" column="COLUMN_NAME" type="java.lang.String" />
        <property name="status" column="STATUS" type="java.lang.String" />       
        <property name="lastModBy" column="LAST_MOD_BY" type="java.lang.String" />
        <property name="metricTypeId" column="METRIC_TYPE_ID" type="java.lang.Long" />
        <property name="tableId" column="TABLE_ID" type="java.lang.Long" />
        <property name="dataStewardId" column="DATA_STEWARD_ID" type="java.lang.Long" />
        <property name="xmlSchemaId" column="XML_SCHEMA_ID" type="java.lang.Long" />

    </class>
   
    <query name="com.sbc.netrics.struts.database.Metric.allRecords">
         <![CDATA[
           from com.sbc.netrics.struts.database.Metric as Metric
           where metric_number not like 'DEMO%'
           order by UPPER(metric_name)
         ]]>
     </query>
       
</hibernate-mapping>


Code between sessionFactory.openSession() and session.close():

Full stack trace of any exception that occurs:

Code:
Hibernate: select metric0_.METRIC_ID as METRIC_ID0_, metric0_.LAST_MOD_DATE as LAST_MOD2_0_, metric0_.METRIC_NUMBER as METRIC_N3_0_, metric0_.METRIC_NAME as METRIC_N4_0_, metric0_.METRIC_DESCRIPTION as METRIC_D5_0_, metric0_.DATA_TYPE as DATA_TYPE0_, metric0_.LENGTH as LENGTH0_, metric0_.DECIMALS as DECIMALS0_, metric0_.COLUMN_NAME as COLUMN_N9_0_, metric0_.STATUS as STATUS0_, metric0_.LAST_MOD_BY as LAST_MO11_0_, metric0_.METRIC_TYPE_ID as METRIC_12_0_, metric0_.TABLE_ID as TABLE_ID0_, metric0_.DATA_STEWARD_ID as DATA_ST14_0_, metric0_.XML_SCHEMA_ID as XML_SCH15_0_ from METRIC metric0_ where metric0_.METRIC_ID=?
INFO  - [MetricCRUDAction.getMetric] lastModDate from database: 2005-02-23 08:41:01.0
INFO  - [MetricCRUDAction.getMetric] lastModDate from form: 2005-02-23 08:34:15.0
INFO  - [MetricCRUDAction.getMetric] metric.lastModDate set to: 2005-02-23 08:34:15.0
INFO  - [MetricCRUDAction.processForm] after BeanUtils.copy lastModDate: 2005-02-23 08:34:15.0
INFO  - [MetricCRUDAction.processForm] right before makePersistent lastModDate: 2005-02-23 08:34:15.0
INFO  - [MetricService.makePersistent] persisting lastModDate: 2005-02-23 08:34:15.0
Hibernate: update METRIC set LAST_MOD_DATE=?, METRIC_NUMBER=?, METRIC_NAME=?, METRIC_DESCRIPTION=?, DATA_TYPE=?, LENGTH=?, DECIMALS=?, COLUMN_NAME=?, STATUS=?, LAST_MOD_BY=?, METRIC_TYPE_ID=?, TABLE_ID=?, DATA_STEWARD_ID=?, XML_SCHEMA_ID=? where METRIC_ID=? and LAST_MOD_DATE=?
Hibernate: select xmlschema0_.XML_SCHEMA_ID as XML_SCHE1_, xmlschema0_.XML_SCHEMA as XML_SCHEMA, xmlschema0_.XML_SCHEMA_DESCRIPTION as XML_SCHE3_ from XML_SCHEMA xmlschema0_ order by  xmlschema0_.XML_SCHEMA_ID
INFO  - [MetricCRUDAction.prepareXmlSchemaList] save xmlSchemaList in session
INFO  - [MetricCRUDAction.prepareForm] call prepareDataStewardList
Hibernate: select role0_.ROLE_ID as ROLE_ID, role0_.ROLE_NAME as ROLE_NAME, role0_.ROLE_DESCRIPTION as ROLE_DES3_, role0_.LAST_MOD_DATE as LAST_MOD4_, role0_.LAST_MOD_BY as LAST_MOD5_, role0_.ROLE_GROUP_ID as ROLE_GRO6_ from ROLE role0_ where (role_group_id=? )
INFO  - [MetricCRUDAction.editForm] lastModDate: 2005-02-23 08:41:05.781
INFO  - [HibernateFilter.doFilter] commit transaction via filter


Name and version of the database you are using: Oracle91


The generated SQL (show_sql=true):

Code:
Hibernate: update METRIC set LAST_MOD_DATE=?, METRIC_NUMBER=?, METRIC_NAME=?, METRIC_DESCRIPTION=?, DATA_TYPE=?, LENGTH=?, DECIMALS=?, COLUMN_NAME=?, STATUS=?, LAST_MOD_BY=?, METRIC_TYPE_ID=?, TABLE_ID=?, DATA_STEWARD_ID=?, XML_SCHEMA_ID=? where METRIC_ID=? and LAST_MOD_DATE=?


Debug level Hibernate log excerpt:


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 23, 2005 12:17 pm 
Beginner
Beginner

Joined: Tue Nov 02, 2004 1:34 pm
Posts: 45
The fix was interesting.

Broke work flow
1. retrieve record from database into metric object
2. copy form values over top of metric object (resets timestamp field to original value)
3. persist metric object

Fixed work flow
1. save metric object into session
2. instead of retrieving record from database...retrieve metric object from session
3. copy form values over top of metric
4. persist metric object


The exception when someone tries to save an already changed record works just fine with the second scenario.

I don't understand why. Doesn't the id of the metric record identify the objecct? How does Hibernate know that the metric I saved and retrieve from the session is the same --- but it does not work to retrieve the metric again from the table?

Lee


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 23, 2005 3:18 pm 
Beginner
Beginner

Joined: Tue Nov 02, 2004 1:34 pm
Posts: 45
Ok...having a converstion with myself here....so I must not be R'ingTHM again. (smile)

Ok...discovered the whole "identity" section of the manual. And obviously, that was my original problem....and that's why storing the original object in an HTTPSession variable and then retrieving it from the session worked -- and retrieving the instance from the database did not.

So...I add the equals/hash methods to my Metric class

Code:
    public boolean equals (Object other) {
       System.out.println("equals being run");
       if (this==other) return true;
       if (this.getMetricId()==null) return false;
       if ( ! ( other instanceof Metric)) return false;
       final Metric that = (Metric) other;
       return this.getMetricId().equals(that.getMetricId());
    }
   
    public int hashCode() {
       return this.getMetricId() == null ? System.identityHashCode(this) : this.getMetricId().hashCode();
    }


To no avail. The System.out is never printed. Is there something else I'm supposed to do to have hibernate use my new equals class so that it understands that two java objects with the same metricId value are the same object?

Lee


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.