Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can NHibernate use the database-default value when saving a new entity?

Tags:

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.

like image 602
iammichael Avatar asked Jul 14 '09 16:07

iammichael


2 Answers

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

NHibernate Mapping - property

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.

like image 130
anonymous Avatar answered Oct 12 '22 11:10

anonymous


I had a similar issue. I had to add the attribute dynamic-insert="true" to my class mapping.
From the documentation:

dynamic-insert (optional - defaults to false): specifies that INSERT SQL should be generated at runtime and contain only the columns whose values are not null.
like image 33
ehertlein Avatar answered Oct 12 '22 13:10

ehertlein