tags:

views:

454

answers:

2

Consider the following simple C# class:

public class Entity
{
    public Entity() { }
    public virtual int Id { get; private set; }
    public virtual DateTime DateCreated { get; private set; }
}

Mapped with the following simple NHibernate mapping:

<class name="Entity" mutable="false">
    <id name="Id">
        <generator class="native">
    </id>
    <property name="DateCreated"/>
</class>

To the following simple database schema:

CREATE TABLE Entity (
    Id int IDENTITY(1,1) PRIMARY KEY,
    DateCreated datetime NOT NULL DEFAULT getUtcDate()
)

When creating a new instance of the Entity and saving to the database, how do you instruct NHibernate to use the database's default value for the DateCreated column if its value is null? Alternatively, how can I specify that NHibernate should use the result of the getUtcDate() function as the value for the DateCreated field upon insertion?

While I could easily add

DateCreated = DateTime.Now;

into the Entity constructor, this is using the application server's local clock, and I need to use the database's local clock to ensure consistency when there are multiple application servers each with their potentially non-synchronized local clocks.

A: 

Can't answer the nhibernate question, but in general you'll want to store dates in your database as UTC. No matter what their source, UTC is the same across all servers (assuming the clocks are accurate).

Paul Alexander
In general, yes, agreed. That's why I specified getUtcDate() instead of getDate() in the question. :)
iammichael
+2  A: 

You can specify that the property is generated by the database:

Chatper 5.5 Generated Properties

So for your case you would want to specify:

generated="insert"

This way NHibernate knows after an INSERT it will have to refresh the entity, but after updates DateCreated will not be changed.

You might also have to specify:

update="false" insert="false"

I've never used generated, and I'm not sure if NHibernate infers to set those or you have to do it explicitly.

eyston
Not sure how I missed that in the docs (http://nhforge.org/doc/nh/en/index.html#mapping-generated); I swear I looked at least two times and must have stared right at it.
iammichael
I like your doc links better. I need to start making NH Forge a regular stop.
eyston
Unfortunately this doesn't entirely answer the question. While it works for inserts, for updates you'll need to employ database triggers. NHibernate still does not send "DEFAULT" or "GETUTCDATE()" as part of the UDPATE.
Joseph Daigle