-->
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.  [ 7 posts ] 
Author Message
 Post subject: NHibernate : objects being saved with same timestamps
PostPosted: Fri Feb 23, 2007 4:22 am 
Newbie

Joined: Fri Feb 23, 2007 3:24 am
Posts: 3
Hi

I've just recently started working with NHibernate , and have encountered a few problems. Is it possible that NHibernate might save two objects with same timestamps ?
In my case , I have a .Net 2.0 windows application which has a class called 'Message' which has two properties :
ModifiedDT CreateDT . They are mapped to NHibernate Type : TimeStamp.

NHibernate successfully saves the objects to the databases , but on some occassions ( whch are quite random) , I have found two records being inserted in my Message table with exactly same ModifiedDT and CreateDT values. .. as in same value right down to the millisecond.

The same timestamp records cause a lot of problem as they are later picked and processed by another application in ascending order of their ModifiedDT. The order in which the records get processed is very critical ....and with same timestamps records the order in which they get processed is not certain.

Here are the details :

NHibernate Version : 1.0.2.0

Mapping File :
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">

<class name="Shared.Core.Messaging.Message" table="Message">

<id name="Id" column="MessageId" access="nosetter.camelcase">
<generator class="assigned"/></id>

<property name="Body" column="Message" type="Shared.Core.NHibernate.Messaging.UserTypes.MessageType, Shared.Core" not-null="true" update="false" access="nosetter.camelcase" />

<property name="Status" column="Status" type="Shared.Core.NHibernate.Messaging.UserTypes.MessageStatusType, Shared.Core" not-null="true" access="nosetter.camelcase" />

<property name="ModifiedDT" column="ModifiedDT" type="Timestamp" not-null="true" update="false" access="field.camelcase" />

<property name="CreateDT" column="CreateDT" type="Timestamp" not-null="true" update="false" access="field.camelcase" />

<component name="Header" class="Shared.Core.Messaging.MessageHeader, Shared.Core" access="nosetter.camelcase">

<property name="To" column="AddressTo" type="String" length="100" not-null="false" access="nosetter.camelcase" />

<property name="From" column="AddressFrom" type="String" length="100" not-null="false" access="nosetter.camelcase" />

<property name="Subject" column="Subject" type="String" length="50" not-null="false" access="nosetter.camelcase" />

</component>
/class>
</hibernate-mapping>

The folowing method is responsible for saving the object:

Code:
private void DoSave( Message message, ISessionContext session)
{
    session.SaveOrUpdate(message);
}

whch calls:

public void SaveOrUpdate(object obj)
{
     innerSession.SaveOrUpdate(obj);
}

innerSession is declared as :

private readonly ISession innerSession;


Database : SQL Server 2005

Any help is welcome !
Please let me know if any other details are required

Thanks


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 23, 2007 4:49 am 
Regular
Regular

Joined: Tue Aug 08, 2006 4:28 am
Posts: 96
Location: Hong Kong
Timestamp and property of timestamp type are 2 different things

Timestamp is declared as
Code:
<timestamp ... />


Property of timestamp type is declared as
Code:
<property type="timestamp" ... />



Timestamp is a value for concurrency control. Property of timestamp type has a higher precision than property of DateTime type.

Hope this helps


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 23, 2007 4:50 am 
Regular
Regular

Joined: Tue Aug 08, 2006 4:28 am
Posts: 96
Location: Hong Kong
And I notice that you've put update="false" in ModifiedDT. The value couldn't be updated.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 23, 2007 5:25 am 
Newbie

Joined: Fri Feb 23, 2007 3:24 am
Posts: 3
Thanks a lot for the reply.

Yes I understand that timestamp and "property of timestamp" type are seperate things .... Here I have two poperties of type timestamp .

I tried taking off the 'update=false' tag also .. but the problem stil persists.
Anyways the windows application which generates these records is not meant to update it ... hence the tag..

My issue is that there at times records inserted in the Message table with exactly same datetime values for these fields. Below is a representation of the outut of sql server query analyser whidh shows the modifieddt values for some records just generated... ( have manually copy pasted it ..could show only one field ..otherwise it gets all messed up )

modifieddt
-----------------------
2007-02-23 14:13:25.273
2007-02-23 14:13:13.743
2007-02-23 14:13:13.743

2007-02-23 14:11:56.350
2007-02-23 14:11:56.337


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 23, 2007 6:03 am 
Regular
Regular

Joined: Tue Aug 08, 2006 4:28 am
Posts: 96
Location: Hong Kong
There is one thing that I don't understand. Why do you think ModifiedDt has to be unique? And which layer of the system takes the responsibility to make it unique?

Obviously NHibernate can't make ModifiedDt unique for you because NH treats it as a normal property (you defined it as a property of type timestamp). NH only persists the value you've set to the property to database.

Therefore the responsibility goes to you. How do you set values to ModifiedDt?

Machines now are very fast, 1G (1,000,000,000) instructions could be executed in 1 second. Simple math tells us about 1,000,000 instructions would take place within the same millisecond. (Of course 1 value assignment takes more than 1 instruction but definitely less than 1 million)


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 23, 2007 7:07 am 
Newbie

Joined: Fri Feb 23, 2007 3:24 am
Posts: 3
We require the ModifiedDT values to be unique as these records are later processed by another application ( a windows service actually ) which picks them in ascending order of ModifiedDT . The records have to get
processed in the right order .... which is not possible if I have records with similar ModifiedDt values

The windows application creates the 'Message' record and assigns the values to the createdt and modifieddt fields.

This is the constructor of the Message class :

Code:
protected Message(string to, string from, string subject, IXPathNavigable body, DateTime createDateTime, DateTime modifiedDateTime)
        {
            header = new MessageHeader(to, from, subject);
            this.body = body;
            id = Guid.Empty;
            status = MessageStatus.New;
            modifiedDT = modifiedDateTime;
            createDT = createDateTime;
        }

When we instantiate a Message object , we set its ModifiedDT and CreateDT to DateTime.UtcNow. These values are not altered at any time once they are set.

The DoSave method does get called in something like a loop ... multiple times
So as you say , is it possible that within 1 millisecond , the DoSave method gets called twice ..which results in two Message objects being assigned the same datetime values ..?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 23, 2007 8:52 am 
Contributor
Contributor

Joined: Sat Sep 24, 2005 11:25 am
Posts: 198
You cannot guarantee unique timestamp.
Assuming that you have SQL Server, datetime is limited to 3 milliseconds accuracy.
I would suggest adding an IDENTITY field and working with that, since that is guranteed to work.


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