Mapping to a backing field with Fluent NHibernate v1.3.0.717

887 views
Skip to first unread message

heads5150

unread,
Oct 3, 2011, 5:53:36 AM10/3/11
to Fluent NHibernate
I am using Fluent NHibernate v1.3.0.717 and vNHibernate 3.2.0.4000
pulled down from NuGet

I have a model

public class Gift
{
private readonly IList<Asset> _assets = new List<Asset>();

public virtual long Id { get; set; }
public virtual string Name { get; set; }
public virtual string ShortDescription { get; set; }

public virtual IEnumerable<Asset> GetAssets()
{
return _assets;
}

public virtual void Add(Asset asset)
{
_assets.Add(asset);
}

public virtual void Remove(Asset asset)
{
_assets.Remove(asset);
}

public virtual decimal Price { get; set; }
}

Which is mapped as follows:

public class GiftMap : ClassMap<Gift>
{
public GiftMap()
{
Id(x => x.Id).GeneratedBy.Identity();
Map(x => x.Name).Length(255).Not.Nullable();
Map(x => x.Price).Not.Nullable();
Map(x => x.ShortDescription).Length(140).Not.Nullable();
HasMany(x =>
x.GetAssets()).Access.CamelCaseField(Prefix.Underscore).ReadOnly().AsList();
}
}

when I try to run the code I get the following error

----> NHibernate.MappingException : Could not compile the mapping
document: (XmlDocument)
----> NHibernate.PropertyNotFoundException : Could not find the
property '_assets', associated to the field '__assets', in class
'BlogSamples.Core.Domain.Gift'

I can't workout why it's occurring?

Mr Bretticus

unread,
Oct 4, 2011, 5:22:41 AM10/4/11
to fluent-n...@googlegroups.com
Try changing GetAssets() to a read-only property:

Assets { get { return _assets; } }

James Gregory

unread,
Oct 4, 2011, 11:02:20 AM10/4/11
to fluent-n...@googlegroups.com
Try removing your Access call all together. There was a change made around the 1.2 release where FNH would try to auto-detect the access strategy depending on your class design. I'm guessing something isn't quite working right there and it's prepending an extra underscore.

heads5150

unread,
Oct 5, 2011, 6:00:30 PM10/5/11
to fluent-n...@googlegroups.com
Changing the line

HasMany(x =>
x.GetAssets()).Access.
CamelCaseField(Prefix.Underscore).ReadOnly().AsBag();


HasMany(x => x.GetAssets()).ReadOnly().AsBag();

Gives me this error:

System.ArgumentException : Not a member access
Parameter name: expression

@James Gregory Exporting the xml created from HasMany(x =>
x.GetAssets()).Access.
CamelCaseField(Prefix.Underscore).ReadOnly().AsBag();
 
is

 <bag access="field.camelcase-underscore" inverse="true" name="_assets" mutable="false">
      <key>
        <column name="Gift_id" />
      </key>
      <one-to-many class="BlogSamples.Core.Domain.Asset, BlogSamples.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    </bag>

I think NHibernate itself adds prepends the extra underscore on so:
_assets becomes __assets

whereas I think the correct hbm output would be

 <bag access="field.camelcase-underscore" inverse="true" name="assets" mutable="false">

which NHibernate would interpret as _assets

I maybe though


heads5150

unread,
Oct 5, 2011, 6:02:36 PM10/5/11
to fluent-n...@googlegroups.com
That gives me the error:
System.ApplicationException : Error while trying to set property Assets
  ----> System.ArgumentException : Property set method not found.

Mr Bretticus

unread,
Oct 5, 2011, 10:57:21 PM10/5/11
to fluent-n...@googlegroups.com
The following works for me in version 1.0, so perhaps as James says the later changes broke it.

public class Parent {
        private readonly IList<Child> _children = new List<Child>();
public virtual IEnumerable<Child> Children {
get { return _children; }
}
}

public class ParentMappingOverride : IAutoMappingOverride<Parent>
{
public void Override(AutoMapping<Parent> mapping) {
mapping.HasManyToMany(p => p.Children)
.Access.CamelCaseField(Prefix.Underscore)
.AsList();
}
}

<hibernate-mapping ...>
<class ...>
...
<list access="field.camelcase-underscore" name="Children" ... />
...
</class>
</hibernate-mapping>

James Gregory

unread,
Oct 7, 2011, 5:58:35 AM10/7/11
to fluent-n...@googlegroups.com
I think you're right. This sounds like a breaking change in NHibernate :(
Reply all
Reply to author
Forward
0 new messages