Mapping By Code, priority of customization.

38 views
Skip to first unread message

Neo

unread,
Jul 29, 2011, 5:03:05 AM7/29/11
to nhusers
(this is using v3.2.0.3001)
If I want to set the default max string length for all properties of
my entities I would use something like:
mapper.BeforeMapProperty += (inspector, member, customizer) =>
customizer.Length(128);

But if I want to customize some specific property to be varchar(max),
I guessed that I could simply use:
mapper.Class<Student>(map => map.Property(s => s.Notes, pm =>
pm.Type(NHibernateUtil.StringClob)));

however, the "BeforeMapProperty" seems to be executed after the
"Class" customization.
Is this the intended behavior, and I should do this in some other way?

Cheers!

Fabio Maulo

unread,
Jul 30, 2011, 8:58:43 AM7/30/11
to nhu...@googlegroups.com
it is executed before but you have to specify the len in the customizer
mapper.Class<Student>(map => map.Property(s => s.Notes, pm => {pm.Type(NHibernateUtil.StringClob); pm.Length(int.MaxValue)})); 

Neo

unread,
Jul 30, 2011, 3:32:03 PM7/30/11
to nhusers
Ah, makes sense.
Thanks!

Neo

unread,
Jul 30, 2011, 6:51:03 PM7/30/11
to nhusers
Just tried it and it doesn't work either, the length is still set
according to the "BeforeMapProperty" customizer.
Maybe I should file a jira?
> > => {pm.Type(NHibernateUtil.StringClob); pm.Length(int.MaxValue)}));- Dölj citerad text -
>
> - Visa citerad text -

Fabio Maulo

unread,
Jul 31, 2011, 6:14:12 PM7/31/11
to nhu...@googlegroups.com
before do it, please try to create a failing test outside your system... I'm afraid that you are doing something wrong somewhere else in your mappimg.

Neo

unread,
Aug 1, 2011, 12:43:44 PM8/1/11
to nhusers
So I did, it's still reproducible when I have 1 entity with just one
property. I managed to find out that it follows this pattern:

int stringLength = int.MaxValue;
mapper.Class<Student>(map => map.Property(c => c.Notes, pm =>
{ pm.Type(NHibernateUtil.StringClob); pm.Length(stringLength); }));

when stringLength is up to and including 4000, it will create a column
in the database with an equal length (i.e nvarchar(0-4000))
when stringLength is from 4001 up to and including int.MaxValue / 2,
it will become nvarchar(max).
BUT when stringLength is from (int.MaxValue/2)+1 up to and including
int.MaxValue, it will become nvarchar(256).

A bug report has been filed at: https://nhibernate.jira.com/browse/NH-2818

If this is the intended behavior for some reason, then please
disregard this.

Cheers!

Fabio Maulo

unread,
Aug 1, 2011, 7:05:04 PM8/1/11
to nhu...@googlegroups.com
Then the XML mapping has the same problem.

Neo

unread,
Aug 2, 2011, 4:32:44 PM8/2/11
to nhusers
I had a look at the NHibernate source, and yes, that's correct. I'll
write this here for future reference.
In my case as I'm using Microsoft SQL Server to connect to, there is a
const defined in SqlClientDriver called MaxSizeForClob, which is
defined as int.maxvalue/2.
so a proper setup for a string property to become nvarchar(max) could
be like this:
mapper.Class<Student>(map => map.Property(c => c.Notes, pm =>
{ pm.Type(NHibernateUtil.StringClob);
pm.Length(SqlClientDriver.MaxSizeForClob); }));

Could this be because each "nvarchar" is stored as 2 bytes in the
database, and hence the total max storage would be int.MaxValue/2 * 2
i.e int.MaxValue?
Reply all
Reply to author
Forward
0 new messages