NHibernate config properties in Fluent NHibernate - nhibernate

I am considering using Fluent NHibernate for my project and I haven't found any documentation on whether FH supports NHibernate settings such as show_sql and prepare_sql. I could live without show_sql in a pinch, but prepare_sql is important for ensuring good performance at run time.
Can anyone tell me if it's possible to configure these settings in Fluent NHibernate?

Yes, you can.
Fluently.Configure()
.Database(ConfigureDatabase())
.Mappings(ConfigureMapping)
.ExposeConfiguration(ModifyConfiguration)
.BuildConfiguration();
And now in ModifyConfiguration method you have plain NHibernate's Configuration object to modify
private void ModifyConfiguration(Configuration configuration)
{
// set parameters here like this:
configuration.Properties["show_sql"] = "true";
}

Some of the settings are exposed through the fluent API.
See here for examples: Database Configuration
Anything that isn't supported through specific fluent calls can be set by manipulating the native NHibernate.Cfg.Configuration object. Either way you can do everything in code that you can with the configuration file.

Related

Splitting configuration in Fluent NHibernate

I am trying to split the configuration in Fluent NHibernate between two classlibraries (dll's).
The first classlibrary would configure certain listeners in NHibernate (for auditing and security) and the second would map/automap the entities. Any good ideas for how to pass the Fluent config between the libraries?
One idea I have is using Castle Windsor (part of my infrastructure already) and installers to pass the config via the container between the libraries. Does that sound reasonable?
i have a similar scenario where configure the mappings somewhere else. I dont pass the config around, i just take the mappings as a whole from different providers.
For example:
Fluently.Configure()
.Mappings(m => m.AutoMappings.Add(Container.Resolve<IAutoMapProvider>().Get())
public class AutoMapProvider : IAutomapProvider
{
...
public static AutoPersistenceModel Get()
{
return AutoMap
.AssemblyOf<MyObjectBase>(new MyConfiguration())
.IgnoreBase<MyObjectBase>()
.Conventions.Setup(c =>
// ...
}
}

What is Castle proxy factory in NHibernate?

What is Castle proxy factory in NHibernate? What is its task? What does proxy mean in this case?
Castle can be used (amongst others, you have the choice, you can also use LinFu, Spring.NET, ...) to create dynamic proxies of your entities.
By default, NHibernate uses dynamic proxies to represent your entities; by doing so, it is able to return an object to you when you retrieve some entity from the DB, without all properties being populated. By using a dynamic proxy, it will only populate the entity once you really refer to a property.
(So it is some kind of lazy loading; not to be confused with lazy loading of collections / associations though).
This behaviour is the reason why NHibernate wants you to create every property as virtual by default: NHibernate will create a new class using this Castle (or LinFu, ...) proxy provider which inherits from your entity, and it will override all the properties so that it can 'inject' the code that is necessary to retrieve the necessary data from the DB.
You can disable this behaviour by specifying 'lazy=false' in your entity mapping. (Although, I do think that even if you disable this feature, NHibernate will still require that you use one of the proxy factories).
When you are selecting an entity from ISession you are getting not real entity instance - you are getting proxy object.
This proxy object inherits your entity and used by NHibernate to track changes made to the fields.
see it: http://en.wikipedia.org/wiki/Proxy_pattern

Weird override problem with Fluent NHibernate and .NET 4

I recently asked a question about using Fluent NHibernate with .NET 4 - I solved that problem, but met a new one.
Summary
My main problem (at the moment) is configuring the database. I'm following this guide, but trying to work against SQL Server 2008 Express instead, as that's what I'll be using and thus what I need to learn.
The failing code:
public static ISessionFactory CreateSessionFactory()
{
return Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008.ConnectionString(c => c.FromConnectionStringWithKey("mssql")))
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<Program>())
.ExposeConfiguration(cfg => new SchemaExport(cfg).Create(true, true))
.BuildSessionFactory();
}
When I try to run my application, I get the following exception on the last line (.BuildSessionFactory()):
Inheritance security rules violated while overriding member: 'FluentNHibernate.Cfg.FluentConfigurationException.GetObjectData(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)'. Security accessibility of the overriding method must match the security accessibility of the method being overriden.
What is causing this?
From the Microsoft Connect issue:
Security attributes need to be
re-applied on types that derive from
other types that also have security
attributes.
Maybe FluentConfigurationException needs to apply a [SecurityPermission] attribute to its GetObjectData() method.
Else check out this blog post.
EDIT: The final solution was adding [SecurityCritical] to FluentConfigurationException.GetObjectData()

adding an nHibernate mapping at run time?

Background:
I'm getting a mapping failure when trying to use nHibernate. The application consists of several assemblies. One of the assemblies is a library of useful routines and the other is application code that uses the library. The library assembly adds itself to the nHibernate configuration but since it doesn't know about other assemblies it doesn't add them. My xml mapping file is located in the application assembly. I think it's not finding it because it's not looking in the application assembly.
Question:
Can you map to a class in an arbitrary assembly without adding it to the configuration?
If not, can you add a mapping at run time?
Thanks
p.s.
I did make sure the mapping file was marked as an embedded resource
Update - Apr 3 '09
I changed the underlying library to allow adding assemblies at initialization. That seems to work just great.
You can add mappings at runtime at the moment your session factory is being constructed:
ISessionFactory sf = new Configuration()
.AddFile("Item.hbm.xml")
.AddFile("Bid.hbm.xml")
.BuildSessionFactory();
or with assemblies:
ISessionFactory sf = new Configuration()
.AddAssembly("NHibernate.Auction")
.BuildSessionFactory();
Re your comment - no you cannot add mappings once you constructed your session factory. You can however re-create the session factory. Keep in mind though that it can be expensive operation (a second or so).

NHibernate.MappingException: Unknown entity class

I am trying to get test running that uses FluentNHibernate to map my
entities.
I get unknown entity class error.
I have a Domain project that has my entities and the mappings in a seperate
folder in that project.
My test project has the Nhibrenate configuration in the App.Config.
Any ideas please???
Malcolm
EDIT: I have this method that creats the ISessionFactory but I dont think this code is working and this is why it does not recoginze me mappings exist at all. The SessionFacoryCreator is the assembly with my AppConfig and Recipe is my assembly where the Domain objects are. Please HELLLLLLP!!!!
public static ISessionFactory Create()
{
Configuration cfg = new Configuration()
.AddAssembly(typeof(SessionFactoryCreator).Assembly)
.AddAssembly(typeof(Recipe).Assembly);
return cfg.BuildSessionFactory();
}
Have you read the wiki? Your example shows nothing of hooking Fluent NHibernate into the session factory building, that'd be why it isn't working. Start with the Getting Started guide.
How do you add your Entities to the Hibernate framework? Are you using AnnotationConfiguration or just Configuration? If you are using annotations you must add your annotated entity to the framwork. Otherwise, if you are using xml hibernate mapping, the syntax could be worng (iirc)
NHibernate and I keep on getting the following error: MappingException: Unkown Entity Class
If you get MappingException error, there are two things you should check out:
Make sure the name of the *.hbm.xml is spelled correctly — not *.hmb.xml nor *.mbh.xml
Make sure the Build Action property is set to “Embeded Resource.”