I am new to Fluent NHibernate (as well as NHibernate itself), but so far I love i!. One of the main things that prevented my earlier migration to NH was a complete lack of enthusiasm for dealing with those cumbersome XML files. James and the rest of the folks have created an amazing tool. (I really appreciate your relieving us all of that configuration tedium. Thank you!)
As I educate myself on Fluent, I continue to run into minor problems-- mostly of my own making. I have been attempting to work with the AutoMapping feature but am having difficulty. I am sure it's just me, but I simply am unaware of how to resolve the issues. Following are two issues I am currently having. 1. The getting started wiki (http://wiki.fluentnhibernate.org/ Getting_started) defines a sample with store, product, and employee classes. It also defines the mapping for those classes. I replaced the manual mapping with AutoMapping and the schema generated properly. However, when the application attempted to save the file, I received an error "TransientObjectException was Unhandled: object references an unsaved transient instance - save the transient instance before flushing. Type: FluentExample.Entities.Employee, Entity: FluentExample.Entities.Employee". The automap looks like: .Mappings(m=> m.AutoMappings.Add( AutoMap.AssemblyOf<FluentExample.Entities.Employee> (type => type.Namespace == "FluentExample.Entities"))) The object creation code (straight from the wiki) looks like. // create a couple of Stores each with some Products and Employees var barginBasin = new Store { Name = "Bargin Basin" }; var superMart = new Store { Name = "SuperMart" }; var potatoes = new Product { Name = "Potatoes", Price = 3.60 }; var fish = new Product { Name = "Fish", Price = 4.49 }; var milk = new Product { Name = "Milk", Price = 0.79 }; var bread = new Product { Name = "Bread", Price = 1.29 }; var cheese = new Product { Name = "Cheese", Price = 2.10 }; var waffles = new Product { Name = "Waffles", Price = 2.41 }; var daisy = new Employee { FirstName = "Daisy", LastName = "Harrison" }; var jack = new Employee { FirstName = "Jack", LastName = "Torrance" }; var sue = new Employee { FirstName = "Sue", LastName = "Walkters" }; var bill = new Employee { FirstName = "Bill", LastName = "Taft" }; var joan = new Employee { FirstName = "Joan", LastName = "Pope" }; // add products to the stores, there's some crossover in the products in each // store, because the store-product relationship is many-to-many AddProductsToStore(barginBasin, potatoes, fish, milk, bread, cheese); AddProductsToStore(superMart, bread, cheese, waffles); // add employees to the stores, this relationship is a one-to-many, so one // employee can only work at one store at a time AddEmployeesToStore(barginBasin, daisy, jack, sue); AddEmployeesToStore(superMart, bill, joan); // save both stores, this saves everything else via cascading session.SaveOrUpdate(barginBasin); session.SaveOrUpdate(superMart); transaction.Commit(); 2. When attempting to use the AutoMap functionality, a class is created, but for some reason I get errors when I attempt to actually insert a record. The main error message says "AssertionFailure was unhandled: null value". Here is a sample of my class, the config/ mapping, the error, and the create table script. (Note: The attributes in the class are for use with ASP.NET MVC and have nothing to do with NH.) using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using FluentNHibernate.Mapping; namespace Credit.Data.Entities { /// <summary> /// /// </summary> [Serializable] public class EthnicityType { #region Default ( Empty ) Class Constuctor /// <summary> /// default constructor /// </summary> public EthnicityType() { } #endregion // End of Default ( Empty ) Class Constuctor #region Public Properties /// <summary> /// /// </summary> [DisplayName("Id")] [Required(ErrorMessage = "Id is required.")] public virtual Guid Id { get; private set; } /// <summary> /// /// </summary> [DisplayName("Title")] [Required(ErrorMessage = "Title is required.")] [StringLength(80, ErrorMessage = "Title must be less than 80 characters.")] public virtual string Title { get; set; } /// <summary> /// /// </summary> [DisplayName("Description")] [StringLength(255, ErrorMessage = "Description must be less than 255 characters.")] public virtual string Description { get; set; } /// <summary> /// /// </summary> [DisplayName("Is Active")] [Required(ErrorMessage = "Is Active is required.")] public virtual bool IsActive { get; set; } /// <summary> /// /// </summary> [DisplayName("Created On")] [Required(ErrorMessage = "Created On is required.")] public virtual DateTime CreatedOn { get; set; } /// <summary> /// /// </summary> [DisplayName("Created By")] public virtual Guid CreatedBy { get; set; } /// <summary> /// /// </summary> [DisplayName("Updated On")] public virtual DateTime UpdatedOn { get; set; } /// <summary> /// /// </summary> [DisplayName("Updated By")] public virtual Guid UpdatedBy { get; set; } #endregion } } private static ISessionFactory CreateSessionFactory() { return Fluently.Configure() .Database(MsSqlConfiguration.MsSql2008 .ConnectionString(c => c.FromConnectionStringWithKey ("CreditConnectionString")) .UseReflectionOptimizer() .AdoNetBatchSize(25) .DefaultSchema("dbo") .Cache(c => c .UseQueryCache() .ProviderClass<HashtableCacheProvider>()) .ShowSql()) .Mappings(m=> m.AutoMappings.Add( AutoMap.AssemblyOf<Credit.Data.Entities.EthnicityType>(type => type.Namespace == "Credit.Data.Entities"))) .ExposeConfiguration(BuildSchema) .BuildSessionFactory(); } NHibernate.AssertionFailure was unhandled Message="null identifier" Source="NHibernate" StackTrace: at NHibernate.Engine.EntityKey..ctor(Object identifier, String rootEntityName, String entityName, IType identifierType, Boolean batchLoadable, ISessionFactoryImplementor factory, EntityMode entityMode) at NHibernate.Engine.EntityKey..ctor(Object id, IEntityPersister persister, EntityMode entityMode) at NHibernate.Event.Default.AbstractSaveEventListener.PerformSaveOrReplicate (Object entity, EntityKey key, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess) at NHibernate.Event.Default.AbstractSaveEventListener.PerformSave(Object entity, Object id, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess) at NHibernate.Event.Default.AbstractSaveEventListener.SaveWithGeneratedId (Object entity, String entityName, Object anything, IEventSource source, Boolean requiresImmediateIdAccess) at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.SaveWithGeneratedOrRequestedId (SaveOrUpdateEvent event) at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.EntityIsTransient (SaveOrUpdateEvent event) at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.PerformSaveOrUpdate (SaveOrUpdateEvent event) at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.OnSaveOrUpdate (SaveOrUpdateEvent event) at NHibernate.Impl.SessionImpl.FireSaveOrUpdate (SaveOrUpdateEvent event) at NHibernate.Impl.SessionImpl.SaveOrUpdate(Object obj) at FluentExample.Program.PopulateRecordTest(ISessionFactory sessionFactory) in C:\Code\FluentExample\FluentExample\Program.cs:line 52 at FluentExample.Program.BootstrapNH() in C:\Code\FluentExample \FluentExample\Program.cs:line 32 at FluentExample.Program.Main() in C:\Code\FluentExample \FluentExample\Program.cs:line 24 at System.AppDomain._nExecuteAssembly(Assembly assembly, String [] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart() InnerException: USE [Credit] GO /****** Object: Table [dbo].[EthnicityType] Script Date: 08/30/2009 04:59:31 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[EthnicityType]( [ID] [uniqueidentifier] NOT NULL, [Title] [nvarchar](80) NOT NULL, [Description] [nvarchar](255) NULL, [IsActive] [bit] NOT NULL, [CreatedOn] [datetime] NOT NULL, [CreatedBy] [uniqueidentifier] NULL, [UpdatedOn] [datetime] NULL, [UpdatedBy] [uniqueidentifier] NULL, CONSTRAINT [PK_EthnicityType_Title] PRIMARY KEY NONCLUSTERED ( [ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO ALTER TABLE [dbo].[EthnicityType] ADD CONSTRAINT [DF_EthnicityType_ID] DEFAULT (newid()) FOR [ID] GO ALTER TABLE [dbo].[EthnicityType] ADD CONSTRAINT [DF_EthnicityType_IsActive] DEFAULT ((1)) FOR [IsActive] GO ALTER TABLE [dbo].[EthnicityType] ADD CONSTRAINT [DF_EthnicityType_CreatedOn] DEFAULT (getdate()) FOR [CreatedOn] GO I've tried a number of things to get automapping working in my environment but just have not yet been fully successful. Some variations I have tried include - Using a static map and allowing Fluent Nhibernate to recreate my table. - Removing CreatedBy/UpdatedBy/CreatedOn/UpdatedOn from table and class in case uniqueidentifier might be causing problems. (I do eventually plan to have the CreatedBy/UpdatedBy map to my user table through conventions.) - Changing the private set on Id to public - Creating a primarykeyconvention to try and set the Guid in case that was the issue and adding this to my mapping. (See below.) public class PrimaryKeyConvention : IIdConvention { public void Apply(IIdentityInstance instance) { instance.GeneratedBy.GuidComb(); //instance.GeneratedBy.Native(); } } Any advice or feedback is very much appreciated. Thanks for all your help! Anthony --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
