I recently upgraded FluentNHibernate from v1.1.0.685 to v1.2.0.712 (latest) for NHibernate 2.1.
My issue appears to be with classes that use the Component().ColumnPrefix()
mapping.
For example,
public class Address{
public string Street {get; set;}
public string Zip {get; set;}
}
public class AddressMap : ComponentMap<Address>{
Map( x => x.Street );
Map( x => x.Zip );
}
public class PersonMap : ClassMap<Person>
{
public PersonMap(){
Id( x => x.Id );
Map( x=> x.Name );
Component( x => x.Address )
.ColumnPrefix("ADDRESS_");
}
}
Person Table
Id Name ADDRESS_Street ADDRESS_Zip
----------------------------------------------------
1 Brian 123 Example St. 12345
Behavior in FNH v1.1.0.685
The "ADDRESS_" prefix is correctly applied to the properties of the Address component.
Behavior in FNH v1.2.0.712 (latest)
The "ADDRESS_" prefix is no longer applied to the properties of the Address component. NHiberante generates "Street" and "Zip" columns which are not named in table above.
I'd appreciate if anyone has any insight. I'm beginning to think this might be a bug.
Thanks,
Brian
@Brian,
I hit the exact roadblock a few weeks ago. I'm using automappings and got around it by creating a Component Property Convention:
Public Class ComponentPropertyConvention
Implements IPropertyConvention, IPropertyConventionAcceptance
Public Sub Accept(ByVal criteria As IAcceptanceCriteria(Of IPropertyInspector)) Implements IConventionAcceptance(Of IPropertyInspector).Accept
criteria.Expect(Function(inspector) inspector.EntityType.Namespace.EndsWith("Components"))
End Sub
Public Sub Apply(ByVal instance As IPropertyInstance) Implements IConvention(Of IPropertyInspector, IPropertyInstance).Apply
instance.Column(String.Format("{0}_{1}", New String() {instance.EntityType.Name.ToLower(), instance.Property.Name.Dbize()}))
End Sub
End Class
There's probably a wealth of ways to implement your acceptance criteria so don't follow mine if it doesnt suit...
Cheers
After investigating the unit tests in the source code; it appears that, in my case, my conventions were being applied differently between FNH v1.1 and FNH v1.2.
I think this is what happened:
My AddressMap : ComponentMap<Address>
would get executed (no problem here).
My PersonMap : ClassMap<Person>
would map a component using:
Component( x => x.Address ).ColumnPrefix("ADDRESS_");
from Step 1.
My FNH MyPropertyConvention
would call:
public class MyPropertyConvention : IPropertyConvention
{
public void Apply( IPropertyInstance instance )
{
instance.Column( instance.Name ); //this call is destructive
//to ColumnPrefix() in FNH v1.2
}
}
It appears:
in FNH v1.1, Step 3 is not destructive to the column prefix when calling instance.Column()
.
in FNH v1.2, Step 3 is destructive to any ColumnPrefix()
previously set and over-writes the entire column name (including the prefix).
So, I cleaned up my conventions for FNH 1.2 using IPropertyConventionAcceptance
being careful about my calls to instance.Column(instance.Name)
[now that calls are destructive to column prefixes].
Thanks for everyone's help,
Brian
You need to create a ComponentMap<Address>
class in order for the ColumnPrefix
to be applied.
See here: http://wiki.fluentnhibernate.org/Fluent_mapping#ComponentMap.3CT.3E