views:

965

answers:

4

When using fluent configuration to specify fluent mappings like this:

.Mappings(m => m.FluentMappings.AddFromAssembly(typeof(UserMapping).Assembly))

At the moment I am getting a "NHibernate.MappingException : No persister for" error.

Is it a problem that my Entities and my ClassMaps are in different assemblies? Presumably AddFromAssembly is interested in the assembly that holds the class maps, not the entities? (that is what I have assumed)

Thanks!

UPDATE:

Sorry for not responding to answers very quickly - I had to travel unexpectedly after setting the bounty.

Anyway, thanks for the responses. I've taken a look through them and have updated my code to use AddFromAssemblyOf rather than AddFromAssembly, but still am getting the same error. Possibly I am doing something stupid. Here is the full code for the session factory code I am using:

public class NHibernateHelper
    {
        private static ISessionFactory _sessionFactory;
        private static ISessionFactory SessionFactory
        {
            get
            {
                if (_sessionFactory == null)
                {
                    var mysqlConfig = FluentNHibernate.Cfg.Db.MySQLConfiguration
                        .Standard
                        .ConnectionString("CONNECTION STRING OMITTED")
                        .UseOuterJoin()
                        .ProxyFactoryFactory("NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle");

                    _sessionFactory = FluentNHibernate.Cfg.Fluently.Configure()
                                        .Database(mysqlConfig)
                                        .Mappings(m => m.FluentMappings.AddFromAssemblyOf<User>())
                                        .BuildSessionFactory();


                }

                return _sessionFactory;
            }
        }

        public static ISession OpenSession()
        {
            return SessionFactory.OpenSession();
        }
    }

I receive this exception when trying to run a test in nunit that makes use of a repository using this session mechanism:

NHibernate.MappingException : No persister for: xxxx.Model.Entities.User

Thanks

P.S.: I've tried using both and in AddFromAssemblyOf(); Project with mapping definitions (DataAccess) has reference to project with entities (Model).

+1  A: 

Is it a problem that my Entities and my ClassMaps are in different assemblies?

No there is nothing wrong with that as long as you ClassMap project have refrerence to your Entities project

anyway try this :

m.FluentMappings.AddFromAssemblyOf<UserMapping>()

if this doesn't work post the entire error

Yassir
Thanks for the response.
UpTheCreek
+1  A: 

Certainly having your entities in a different assembly should not cause a problem as Yassir alludes to above.

According to the Fluent NHibernate Wiki the AddFromAssemblyOf method infers or reflects on the Assembly that contains all of your entities and will map to them when you supply any entity name to it. From the documentation on the FNH wiki you would construct the method as follows:

 m.FluentMappings
  .AddFromAssemblyOf<YourEntity>();

Therefore in your example, if the entity you are mapping is named User then your code should be constructed as follows:

 m.FluentMappings
  .AddFromAssemblyOf<User>();

Hope this is of help.

JohnL
Thanks for the response.
UpTheCreek
Now fixed, but in the end it would not work with AddFromAssemblyOf<YourEntity>(); it had to be AddFromAssemblyOf<YourEntityMapping>(); Perhaps the FNH wiki is wrong?
UpTheCreek
+1  A: 

has this been solved? if not could you inlcude your setup?

for example here is my example one

public static ISessionFactory GetSessionFactory()
    {
        //Old way, uses HBM files only
        //return (new Configuration()).Configure().BuildSessionFactory(); //requies the XMl file.

        //get database settings.
        Configuration cfg = new Configuration();//.Configure();

        ft = Fluently.Configure(cfg);

        //DbConnection by fluent
        ft.Database
            (
            MsSqlConfiguration
                .MsSql2005
                .ConnectionString(c => c
                   .Server(".\\SqlExpress")
                   .Database("NhibTest")
                   .TrustedConnection()
                )
                .ShowSql()
                .UseReflectionOptimizer()
            );

        //set up the proxy engine
        //cfg.Properties.Add("proxyfactory.factory_class", "NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle");

        //get mapping files.
        ft.Mappings(m =>
             {
                 //set up the mapping locations
                 m.FluentMappings.AddFromAssemblyOf<PersonMap>();//.ExportTo("C:\\mappingfiles");
                 //m.Apply(cfg);
             });

        //return the SessionFactory
        return ft.BuildSessionFactory();
    }

the project structure is as follows

  • project.Data <- mapping files, and Dao's (also hibernate session manager, containing the above code)
  • project.Core <- POCO's
  • project.UI

also have look here incase you have a mixture of Fluent NHibernate and NHibernate configuration

Finally have a look at S#arp Architectures way, as i think it includes this mixture

NhibernateSession <- function : private static ISessionFactory CreateSessionFactoryFor

Hope this helps

dbones
Thanks for the detailed response - I notice that you are using AddFromAssemblyOf<PersonMap> rather than <Person>, whereas the other replies talk about referencing the assembly with the entities rather than the mapping definitions - perhaps it can be either??
UpTheCreek
Ah, in the end it seems it had to have been AddFromAssemblyOf<PersonMap>, although there seems to be some confusion in the wiki about this.
UpTheCreek
+1  A: 

What version of Fluent NHibernate are you using? There have been problems with the release candidate and the 1.0 release versions. You may want to consider downloading the latest version from the SVN repository.

http://fluent-nhibernate.googlecode.com/svn/trunk/

Additionally, you may want to check the connection string to make sure that it is completely correct, and you want to make sure that "User" below points to a class.

.Mappings(m => m.FluentMappings.AddFromAssemblyOf<User>())

Also, I should mention that when you use AddFromAssemblyOf, fluent will try to map EVERY class in that assembly. If you have any other classes in that namespace you will want to filter them. There are several different ways to accomplish this. The simplest way is to just place all of the POCOs you want to map in their own namespace and then do something like the following.

.Mappings(m => m.AutoMappings
                .Add(AutoMap.AssemblyOf<MyNamespace.Entities.MyClass>()
                .Where(type => type.Namespace == "MyNamespace.Entities")

The Where clause will filter items you don't want mapped.

Anthony Gatlin
Hi, I'm using release version 1.0.0.593 - and idea where I can find out more about these problems (the FNH community site seems to be down)? I'm fairly certain the connection string is ok. Regarding dialect, is this not enough?: var mysqlConfig = FluentNHibernate.Cfg.Db.MySQLConfiguration.Standard
UpTheCreek
Sosh, your dialect string is fine. I missed it when I reviewed your original post. Regardless of any thing else, I do recommend using the version from SVN along with all of its associated assemblies. I had several problems which disappeared as soon as I updated. Also, suggest using the where clause which I described above. If all else fails, only place one very simple poco class in the namespace you wish to map with only a couple of properties and see if that will work. If that fails, ping me back, and I will try to help.
Anthony Gatlin
Hi, I seemed to have fixed it - it seems to have been that my mapping class was not public. Just a note though, it would not work with .AddFromAssemblyOf<User> it seemed it had to be .AddFromAssemblyOf<UserMapping> - are you sure it should have been <User>. Anyway, I'm giving you the bounty and your comments made me double check in the correct area. Thanks!
UpTheCreek
Thank you Sosh! I am glad you got it to work!
Anthony Gatlin
Do I have to add each "mapping class" when I use .AddFromAssemblyOf<T> ?! Or is there a way of only let the API searching a special Namespace :s? an example would be nice
Rookian