NHibernate 2.* mapping files: how to define nullable DateTime type (DateTime?)? - nhibernate

I know one of the breaking changes with NHibernate 2.* is that the NHibernate.Nullables are no longer supported. Therefore, what do you use in your mapping file to map the nullable DateTime? type? For i.e.:
Understandably doesn't work:
<property name="CreateDate" column="CreateDate" type="DateTime?" not-null="false" />
And no longer supported:
<property name="ModifiedDate" column="ModifiedDate" type="Nullables.NHibernate.NullableDateTimeType, Nullables.NHibernate" not-null="false"/>
I know it must be so obvious, but I'm not finding it!
Answer is as simple as:
NHibernate will reflect over the class in question and discover that the property's reflected type is DateTime? all on its own.
Thanks #Justice!

<property name="CreatedDate" />
NHibernate will reflect over the class in question and discover that the property's reflected type is DateTime? all on its own.
NHibernate will assume the column name is by default the same as the property name, unless you tell it otherwise.
NHibernate will assume that any property is nullable (not-null="false") unless you tell it otherwise.
If you really want, it should be something like ...
<property name="CreatedDate" type="System.Nullable`1[[System.DateTime, mscorlib]], mscorlib" />

Related

How to map an NHibernate entity property using both a formula and a column specification

I'm trying to map an entity property in such way that it writes its value to a database column but retrieves its value using a formula.
To focus on the actual issue, I have simplified the example. In reality the formula is a bit more complex and is using an NHibernate filter.
<many-to-one cascade="all" class="Thing" lazy="false" name="MyThing"
formula="(SELECT Things.Value FROM Things WHERE Things.Id = MyThingId)">
<column name="MyThingId" />
</many-to-one>
The formula is ignored however, unless I remove the <column name="MyThingId" /> line.
How would I fix this mapping in order to have NHibernate use the formula?
I don't think it's possible to do exactly what you are trying.
Why not split the property in two? One readonly for the formula and the other read/write with a direct column mapping...
If you still want a single access point, you can map a third ignored propery that implements it's get and set accessors with the two first properties.

nhibernate table per subclass strategy problem when getting objects

I am working on an ASP.NET Web application that uses NHibernate and I have noticed something funny.
So I have an object Document which I would make into an abstract class and 2 concrete implementations Document1 and Document2.
I tried to write the mappings for them applying the table-per-subclass strategy as described in the documentation(link text):
<class name="Document" abstract="true">
<id name="Id">
<generator class="identity"/>
</id>
...
<class>
<joined-subclass
name="Document1"
extends="Document" >
<key column="ParentId"/>
...
</joined-subclass>
<joined-subclass
name="Document2"
extends="Document" >
<key column="ParentId"/>
...
</joined-subclass>
Now this is how I obtain objects from the session in my application:
public TEntity GetById<TEntity>(object id) {
return Session.Get<TEntity>(id);
}
Now my problem is that when I do:
GetById<Document>(1)
for example, I don't get a Document object I get an object of type Document1 or Document2 depending on which type that object is.
I tryed using the table-per-subclass with discriminators strategy as mentioned in the documentation(link above) and I set join=select and lazy=false on the abstract object to get it to return an object of type Document but nothing worked.
The code works but it doesn't seem right. I have a left join where I could not use one.
Isn't there a way to just get the abstract object or does nhibernate actually instantiate the objects it returns which would make this impossible? Is it possible?
I have the feeling that I am getting more info than I need.
You'll never get the abstract class because the whole point of an abstract class is that you can't instantiate one. Besides your code will return only the Document facade to the rest of your code anyway. So I'm not sure what the problem really is.
It is not possible to retrieve an instance of Document1 or Document2 that only populates the properties that are defined in the abstract class. In .NET, you are always working with an instance of a concrete class even if the type is declared as an interface or abstract class.

NHibernate Property Mapping, best practise for type attribute?

I have a little doubt for mapping of property in hbm file.
Sometimes I've mapped the string field of my db in this way:
<property name="MyPropName" column="MyColumnName" length="20" />
but the same mapping can be wrote in this way:
<property name="MyPropName" column="MyColumnName" type="String(20)" />
my question is...what's the better way?
If I omit "type" attributes for property tags it works, but I don't know if there are some contraindications. Can you tell me?
And last thing...are right this associations?
db varchar fields -> type "AnsiString"
db nvarchar fields -> type "String"
The "best practice" is to only override the defaults. So, for your example, the first form would be the best.
As for the second question: yes, they are correct.
You can find all the value types and default mappings here: 5.2.2. Basic value types

How do I tell NHibernate to load a component as not null even when all its properties are null?

I have a Date class which wraps over the DateTime? class (aids in mocking DateTime.Now, our domain ,etc).
The Date class class only has one protected property : DateTime? date
public class Date
{
protected DateTime? date;
}
// mapping in hbm
<component name="CompletedOn">
<property column="StartedOn" name="date" access="field" not-null="false" />
</component>
From the nhibernate docs:
Like all value types, components do not support shared references. The null value semantics of a component are ad hoc. When reloading the containing object, NHibernate will assume that if all component columns are null, then the entire component is null. This should be okay for most purposes.
Can I override this behaviour? I want my Date class to be instantiated even if date is null.
Thanks,
I think you could achieve this behavior by using a listener that implements IPostLoadEventListener. After the entity is loaded, you can check if the component is null and new it if it is.
I don't think you can override that behavior.
However, it's usually easier to have NH work as usual (retrieving null) and wrap that in your domain model.
But from what I see, it looks like you are doing this maybe for a presentation (data binding?) concern. Isn't it easier to just expose a DateTime??

How do you map enums to and from the database using NHibernate?

Edit: Ryan raised a good point. I specifically want to be able to map to and from while still storing human-readable values in the database. That is, I don't want a bunch of enumeration integers in my database.
According to the documentation you can either leave the type attribute of the property in your mapping file blank or you define it and specify the class name of the enumeration.
Another way would be to convert the enumeration to an int and use the int as the mapped type.
You have to implement a custom IUserType. See this post.
I've never used NHibernate, but can't you just set the SQL datatype to int?
I think you can just set the type to string:
<property name="EnumProperty" Type="string" Length="50" NotNull="true" />