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 access="nosetter.pascalcase-underscore" column="Version"
> > > > name="Version" />
> > > >  </class>
> > > > </hibernate-mapping>
> >
> > > > System.Xml.Schema.XmlSchemaValidationException: The element 'class'
> in
> > > > namespace 'urn:nhibernate-mapping-2.2' has invalid child element
> > > > 'version' in namespace 'urn:nhibernate-mapping-2.2'. List of possible
> > > > elements expected: 'id, composite-id' in namespace 'urn:nhibernate-
> > > > mapping-2.2'.
> > > > -- Exception doesn't have a stack trace --
> > > > NHibernate.MappingException: (XmlDocument)(5,6): XML validation
> error:
> > > > The element 'class' in namespace 'urn:nhibernate-mapping-2.2' has
> > > > invalid child element 'version' in namespace 'urn:nhibernate-
> > > > mapping-2.2'. List of possible elements expected: 'id, composite-id'
> > > > in namespace 'urn:nhibernate-mapping-2.2'.
> > > > at NHibernate.Cfg.Configuration.LogAndThrow(Exception exception)
> > > > at NHibernate.Cfg.Configuration.ValidationHandler(Object o,
> > > > ValidationEventArgs args)
> > > > at System.Xml.Schema.XmlSchemaValidator.SendValidationEvent
> > > > (ValidationEventHandler eventHandler, Object sender,
> > > > XmlSchemaValidationException e, XmlSeverityType severity)
> > > > at System.Xml.Schema.XmlSchemaValidator.ElementValidationError
> > > > (XmlQualifiedName name, ValidationState context,
> > > > ValidationEventHandler eventHandler, Object sender, String sourceUri,
> > > > Int32 lineNo, Int32 linePos, Boolean getParticles)
> > > > at System.Xml.Schema.XmlSchemaValidator.ValidateElementContext
> > > > (XmlQualifiedName elementName, ref Boolean invalidElementInContext)
> > > > at System.Xml.Schema.XmlSchemaValidator.ValidateElement(String
> > > > localName, String namespaceUri, XmlSchemaInfo schemaInfo, String
> > > > xsiType, String xsiNil, String xsiSchemaLocation, String
> > > > xsiNoNamespaceSchemaLocation)
> > > > at System.Xml.XsdValidatingReader.ProcessElementEvent()
> > > > at System.Xml.XsdValidatingReader.ProcessReaderEvent()
> > > > at System.Xml.XsdValidatingReader.Read()
> > > > at System.Xml.XmlLoader.LoadNode(Boolean skipOverWhitespace)
> > > > at System.Xml.XmlLoader.LoadDocSequence(XmlDocument parentDoc)
> > > > at System.Xml.XmlLoader.Load(XmlDocument doc, XmlReader reader,
> > > > Boolean preserveWhitespace)
> >
> > ...
> >
> > read more ยป
> >
>

--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to