That unfortunately raises other issues for me - all my base classes including DomainObject are in another assembly (Core.Common) than the one that holds my domain model (Core.Domain). I don't suppose it's possible to call MapEntitiesFromAssembly<T> more than once and filter it with the same predicate in the Where method? I seem to remember MapEntitiesFromAssembly<T> simply saving a reference to the assembly for use later in CompileMappings which would mean that calling it twice would simply reset the reference. What do you think?
On Feb 12, 8:54 am, James Gregory <[email protected]> wrote: > Yeah, that makes sense. Currently you shouldn't exclude something set with > IsBaseType in your Where clause. That being said, the two should probably > be equivalent really. > > > > On Thu, Feb 12, 2009 at 6:10 AM, Jimit <[email protected]> wrote: > > > I think I may have found the problem. DomainObject was excluded by my > > entity filter in my call to Where on the AutoPersistenceModel (since > > it itself is not an entity, just a common base class for both entities > > and value objects and thus it doesn't have an Id, I figured no need). > > I subsequently did a mapping override using > > ForTypesThatDeriveFrom<DomainObject> which internally populates an > > AutoMap<DomainObject>. In CompileMappings however the conditions that > > would normally exclude DomainObject from the final mapping (i.e the > > checks for shouldInclude and IsBaseType) don't get called for > > DomainObject since it was not in the original list of entities to map. > > It's AutoMap<DomainObject> created by ForTypesThatDeriveFrom is meant > > only to be used by MergeMapping to merge with automaps for classes > > deriving from DomainObject and instead it went to AddMapping. As a > > result it circumvents the checks and ends up getting mapped. Not > > having an Id property, Nhibernate doesn't like that and hence the > > exception. I haven't actually checked the call stacks to verify this > > behaviour - it's all been mental compiler since the realization just > > came to me. :) I'll check it out when I'm at work but it seems to be > > pointing at a loophole in the CompileMapping logic. > > > On Feb 10, 10:54 pm, Jimit <[email protected]> wrote: > > > This is my test fixture. I configure FNH in the Setup: > > > > [TestFixture] > > > public class PersistenceTests > > > { > > > #region Setup/Teardown > > > > [SetUp] > > > public void SetUp() > > > { > > > _sessionFactory = Fluently.Configure() > > > .Database(SQLiteConfiguration.Standard.InMemory) > > > .Mappings(m => m.AutoMappings.Add(Mapper.Mappings)) > > > .ExposeConfiguration(cfg => new SchemaExport > > > (cfg).Create(true, true)) > > > .BuildSessionFactory(); > > > } > > > > [TearDown] > > > public void TearDown() > > > { > > > _sessionFactory = null; > > > } > > > > #endregion > > > > private ISessionFactory _sessionFactory; > > > > [Test] > > > public void Can_Map_Orders_To_Database() > > > { > > > new PersistenceSpecification<Order> > > > (_sessionFactory.OpenSession()) > > > .CheckProperty(o => o.Reference, "Order Ref 1") > > > .CheckProperty(o => o.PartsOrdered, 2) /* and so > > > on...*/ > > > .CheckProperty(o => o.PartsReceived, 1); > > > } > > > > } > > > > Mapper.Mappings is where the AutoPersistenceModel is defined. Here are > > > the pertinent parts there: > > > > public static class Mapper > > > { > > > public static AutoPersistenceModel Mappings > > > { > > > get > > > { > > > return _mappings ?? (_mappings = DefineMappings()); > > > } > > > } > > > > private static AutoPersistenceModel DefineMappings() > > > { > > > return AutoPersistenceModel > > > .MapEntitiesFromAssemblyOf<Order>() > > > .Where(EntityFilter) > > > .WithConvention(DefineConventions) > > > .WithCustomMappingsFrom<CustomMappings>(); > > > } > > > > private static void DefineConventions > > > (FluentNHibernate.Conventions conventions) > > > { > > > SetDefaultConventions(conventions); > > > AddCustomConventions(conventions); > > > } > > > private static void SetDefaultConventions > > > (FluentNHibernate.Conventions conventions) > > > { > > > conventions.GetPrimaryKeyName = property => property.Name > > > + "Id"; > > > conventions.GetPrimaryKeyNameFromType = type => type.Name > > > + "Id"; > > > conventions.GetVersionColumnName = property => "Version"; > > > conventions.IsBaseType = type => > > > type == typeof (object) || > > > type == typeof (DomainObject) || > > > (type.IsGenericType > > > && type.GetGenericTypeDefinition > > > ().IsIn(new[] > > > > { > > > > typeof (EntityBase<,>), > > > > typeof (EntityBase<>), > > > > typeof (ProcessedEntity<,>), > > > > typeof (ProcessedEntity<>), > > > > typeof (AuditedEntity<,>), > > > > typeof (AuditedEntity<>), > > > > typeof (ProcessingEvent<>) > > > })); > > > //conventions.IsComponentType = t => t == typeof(Address); > > > conventions.OneToManyConvention = map => > > > map.Cascade.SaveUpdate(); > > > conventions.DefaultLazyLoad = true; > > > conventions.GetForeignKeyNameOfParent = parent => > > > parent.Name + "ID"; > > > conventions.IdConvention = identity => identity > > > .Access. > > > > AsReadOnlyPropertyThroughPascalCaseField > > > > (Prefix.Underscore) > > > .GeneratedBy.Native > > > () > > > .TheColumnNameIs > > > ("Id"); > > > conventions.GetForeignKeyName = property => property.Name > > > + "Id"; > > > conventions.GetManyToManyTableName = > > > (parent, child) => parent.Name + "_" + child.Name; > > > conventions.DefaultCache = cache => cache.AsReadWrite(); > > > conventions.GetParentSideForManyToMany = (type1, type2) => > > > { > > > var types > > > = (new[] {type1, type2}) > > > .OrderBy > > > (t => t.Name); > > > return > > > types.Where( > > > > t => typeof (IAggregateRoot) > > > .IsAssignableFrom > > > (t)) > > > .FirstOrDefault > > > () ?? > > > > types.First(); > > > }; > > > } > > > > private static void AddCustomConventions > > > (FluentNHibernate.Conventions conventions) > > > { > > > // Add type conventions > > > conventions.AddTypeConvention(new DescriptionTypeConvention > > > ()); > > > conventions.AddTypeConvention(new NameTypeConvention()); > > > conventions.AddTypeConvention(new ReferenceTypeConvention > > > ()); > > > > // Add property conventions > > > conventions.AddPropertyConvention(new > > > ForeignKeyMapsToEnum<Order>(o => o.Status)); > > > conventions.AddPropertyConvention(new AuditingConvention > > > ()); > > > } > > > > public static AutoPersistenceModel > > > WithCustomMappingsFrom<TCustomMapper>(this AutoPersistenceModel model) > > > { > > > (from method in typeof (TCustomMapper).GetMethods() > > > where method.DeclaringType == typeof (TCustomMapper) > > > && method.ReturnType == typeof (void) > > > && method.GetParameters().Count() == 1 && > > > method.GetParameters()[0].ParameterType. > > > GetGenericTypeDefinition() == > > > typeof (AutoMap<>) > > > select method).ForEach(method => > > > { > > > var autoMapType = > > > method.GetParameters()[0].ParameterType; > > > var entityType = > > > autoMapType.GetGenericArguments()[0]; > > > var actionType = typeof > > > (Action<>).MakeGenericType(new[] {autoMapType}); > > > var mappingAction = new[] > > > {Delegate.CreateDelegate(actionType, method)}; > > > > InvocationHelper.InvokeGenericMethodWithDynamicTypeArguments( > > > model, > > > map => > > > map.ForTypesThatDeriveFrom<Object>(null), > > > mappingAction, > > > entityType); > > > }); > > > return model; > > > } > > > > } > > > > The relevent action in CustomMappings is: > > > > public class CustomMappings > > > { > > > public static void ProcessMapping(AutoMap<DomainObject> map) > > > { > > > map.Version(o => o.Version) > > > .Access.AsReadOnlyPropertyThroughPascalCaseField > > > (Prefix.Underscore); > > > map.IgnoreProperty(o => o.IsValid); > > > map.IgnoreProperty(o => o.Error); > > > } > > > > // other mapping overrides > > > } > > > > On Feb 10, 12:07 pm, James Gregory <[email protected]> wrote: > > > > > Can we see how you're setting your conventions and where you're > > plumbing FNH > > > > into NHibernate? > > > > > On Tue, Feb 10, 2009 at 12:01 PM, Jimit <[email protected]> wrote: > > > > > > I get the following error when attempting to test my mappings: > > > > > > <?xml version="1.0" encoding="utf-8"?> > > > > > <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default- > > > > > lazy="true" assembly="Core.Common" namespace="Core.Common.Entities"> > > > > > <class name="DomainObject" table="`DomainObject`" > > > > > xmlns="urn:nhibernate-mapping-2.2"> > > > > > <cache usage="read-write" /> > > > > > <version > > ... > > read more »- Hide quoted text - > > - Show quoted text - --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Fluent NHibernate" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/fluent-nhibernate?hl=en -~----------~----~----~----~------~----~------~--~---
