LocalSessionFactoryObject - MappingResources - Path to the hbm file - c#

The project structure is:
Now I am trying to create a bean NHibernateSessionFactory as:
<object id="NHibernateSessionFactory" type="Spring.Data.NHibernate.LocalSessionFactoryObject, Spring.Data.NHibernate32">
<property name="DbProvider" ref="DbProvider"/>
<property name="MappingResources">
<list>
<value>EMSApplication.Domain/EMSApplication.hbm.xml</value>
</list>
</property>
<property name="HibernateProperties">
<dictionary>
<entry key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider"/>
<entry key="dialect" value="NHibernate.Dialect.MsSql2008Dialect"/>
<entry key="connection.driver_class" value="NHibernate.Driver.SqlClientDriver"/>
<entry key="proxyfactory.factory_class" value="NHibernate.Bytecode.DefaultProxyFactoryFactory, NHibernate"/>
<entry key="show_sql" value="true"/>
<entry key="hbm2ddl.auto" value="update"/>
<entry key="cache.use_query_cache" value="true"/>
</dictionary>
</property>
<property name="ExposeTransactionAwareSessionFactory" value="true" />
</object>
But I am getting the error message:
Error creating context 'spring.root': file [C:\Program Files (x86)\Common Files\Microsoft Shared\DevServer\10.0\EMSApplication.Domain\EMSApplication.hbm.xml] cannot be resolved to local file path - resource does not use 'file:' protocol.
Now the project is on D drive, I am wondering why this is pointing C drive?
Also how can I add the specified hbm file in the mapping resource? This file is set as 'Embedded Resource'.
Is there any way to specify a directory here to scan for the multiple hbm files?
Any information will be very helpful to me.

You are not using a protocol identifier (e.g. file:// or assembly://) in your resource name, so Spring uses the default file protocol. It tries to resolve the hbm file from the location where the web app is running (the devserver path), not where it's files are stored, which you seem to expect.
To reference a file in your website use a ~ to identify the root of your web site, e.g. <value>file://~/EMSApplication.Domain/EMSApplication.hbm.xml</value>. But make sure the file is copied, which might not be the case, since you have set it to embedded resource (why?).
Consider the following improvements, they'll make your live more easy:
move the code in your folders dao, domain and NHibernate to a separate assembly (a class library project that is referenced from your web application) named Your.AssemblyName.
The session factory also supports specifying mapping assemblies to scan, so that you don't have to specify each file - see the docs on setting up a session factory using spring.net. Specify Your.AssemblyName in the mapping assembly list:
<object id="MySessionFactory" type="Spring.Data.NHibernate.LocalSessionFactoryObject, Spring.Data.NHibernate">
<property name="DbProvider" ref="DbProvider"/>
<property name="MappingAssemblies">
<list>
<value>Your.AssemblyName</value>
</list>
</property>
<property name="HibernateProperties">
<!-- snip -->
</object>
And check out the NHibernate example in the spring docs - it's very applicable to the questions you are raising here.

Related

Spring net error

Hi i have problem with following error in spring net
An exception of type 'System.Configuration.ConfigurationErrorsException' occurred in Spring.Core.dll but was not handled in user code
Additional information: Error creating context 'spring.root': Keyword not supported: 'port'.
I have configurtaion in xml for dataprovider ans session factory, where probably is problem but i cant find where. Because when i am remove port (Port=3306;) from datasource definition it work neither
Error
An exception of type 'System.Configuration.ConfigurationErrorsException' occurred in Spring.Core.dll but was not handled in user code
Additional information: Error creating context 'spring.root': The system cannot find the file specified
<db:provider id="DbProvider"
provider="System.Data.SqlClient"
connectionString="Server=127.0.0.1;Port=3306;Database=dbschema;User ID=XXX; Password=XXXX"/>
<object id="NHibernateSessionFactory" type="Spring.Data.NHibernate.LocalSessionFactoryObject, Spring.Data.NHibernate4">
<property name="DbProvider" ref="DbProvider"/>
<property name="MappingAssemblies">
<list>
<value>WarehouseTemplate</value>
</list>
</property>
<property name="HibernateProperties">
<dictionary>
<entry key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider"/>
<entry key="dialect" value="NHibernate.Dialect.MySQL5Dialect"/>
<entry key="connection.driver_class" value="NHibernate.Driver.MySqlDataDriver"/>
<entry key="use_proxy_validator" value="false" />
<entry key="show_sql" value="true"/>
</dictionary>
</property>
<property name="ExposeTransactionAwareSessionFactory" value="true" />
My DB is MySql 5.7. Db is running on local but i want configuratiin with ip because i am planning after test move db elsewhere.

Spring.Net \ DI \ How to read system environment variable

In my dependency injection configuration file - I don't know (and can't find an example) on how to set into a member some predefined environment variable file.
Can't tell how to do it in Spring.Net - your help will be appreciated.
Use an EnvironmentVariableSource, the current docs are somewhat lacking at the moment: http://springframework.net/docs/1.3.2/reference/html/objects.html#objects-variablesource. I've written some additional docs, they'll probably be included in the next 2.0 release of the build. In the meantime you can also check this example code on Github https://github.com/serra/spring-net-examples/tree/master/Spring.IoCQuickStart.VariableSources.
Take a look to the VariablePlaceholderConfigurer object. It should do the job:
http://www.springframework.net/doc-latest/reference/html/objects.html#objects-variablesource
<object type="Spring.Objects.Factory.Config.VariablePlaceholderConfigurer, Spring.Core">
<property name="VariableSources">
<list>
<object type="Spring.Objects.Factory.Config.EnvironmentVariableSource, Spring.Core"/>
</list>
</property>
</object>
<object type="MyObject">
<property name="MyProperty" value="${MyEnvironmentVariableName}"/>
</object>

Nhibernate.Util causing ProxyFactoryFactoryNotConfiguredException when configuration line exists in config

We're building a project using NHibernate and Castle with the Validators project. I'm trying to upgrade it to the latest supported version between all of those. I've gotten the application working without errors, but I'm getting the exception below in a few of my unit tests. These are tests that don't actually touch the database in any way, but test functionality around the mapped entities.
NHibernate.Bytecode.ProxyFactoryFactoryNotConfiguredException:
The ProxyFactoryFactory was not configured.
Initialize 'proxyfactory.factory_class' property of the session-factory
configuration section with one of the available NHibernate.ByteCode providers.
Example:
<property name='proxyfactory.factory_class'>
NHibernate.ByteCode.LinFu.ProxyFactoryFactory, NHibernate.ByteCode.LinFu
</property>
Example:
<property name='proxyfactory.factory_class'>
NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle
</property>
[Continues down stack trace...]
Below is my config file:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2" >
<session-factory name="Linx2">
<property
name="connection.driver_class">NHibernate.Driver.NpgsqlDriver</property>
<property name="dialect">Linx2.Common.Framework.PostgreSQL83Dialect,
Linx2.Common.Framework</property>
<property name="connection.connection_string">[Hidden so I don't get fired.]</property>
<property name="adonet.batch_size">10</property>
<property name="show_sql">false</property>
<property name="use_outer_join">true</property>
<property name="command_timeout">60</property>
<property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
<property name="proxyfactory.factory_class">
NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle
</property>
<property name="connection.release_mode">after_transaction</property>
<mapping assembly="NHibernate.Collection.Observable" />
</session-factory>
</hibernate-configuration>
I have the config mapping there, and it works in the application. I'm also including the NHibernate.ByteCode dll. However, in these tests it is ignored. I've tried manually starting the configuration in individual test and even stopped and confirmed mid-test that the configuration has the item. However, the exception is thrown in the code below on the IsInitialized call.
if (NHibernateUtil.IsInitialized(ChildAssociations))
{
ChildAssociations.ForEach(x => isValid = isValid && x.Element.IsValid(validatedObjects));
}
This worked previously with no problems in NHibernate build for 2.2. Any help would be greatly appreciated. I've been beating my head on it for the last 4 hours.
Apparently NHibernateUtil needs not only to have the configuration initialized, but needs the session factory to be built. I was able to get it to work by manually running the config and building the session factory in the tests. It wasn't a problem in the app because the session factory had been built before hand.
var cfg = new NHibernate.Cfg.Configuration().Configure();
var sessionFactory = cfg.BuildSessionFactory();

NHibernate and Memcached - Tutorial/Example

I have the Membase server installed with a couple buckets setup and I was looking for a good tutorial or example of how to use this as the 2nd level cache with NHibernate.
I am interested in what a sample configuration would look like and if there is anything I need to do in code or if I can handle it all from my NHibernate mappings.
Thanks for any assistance.
In your mapping files, you will need to include the property:
<class name="ClassName" table="Table">
<cache usage="read-write" />
<!-- SNIP -->
</class>
Options are read-write (read committed isolation), nonstrict-read-write (objects that are rarely written, better performance but increased chance of stale data), or read-only (data that never changes).
Then, in your web (or app) config you need a section to configure memcached:
<configuration>
<configSections>
<!-- SNIP -->
<section name="memcache" type="NHibernate.Caches.MemCache.MemCacheSectionHandler,NHibernate.Caches.MemCache" />
</configSections>
<memcache>
<memcached host="127.0.0.1" port="11211" weight="2" />
</memcache>
<!-- SNIP -->
</configuration>
Finally, in your session factory configuration be sure to use:
<hibernate-configuration>
<session-factory>
<!-- SNIP -->
<property name="expiration">300</property> <!--memcache uses seconds -->
<property name="cache.provider_class">NHibernate.Caches.MemCache.MemCacheProvider,NHibernate.Caches.MemCache</property>
<property name="cache.use_second_level_cache">true</property>
<property name="cache.use_query_cache">false</property> <!-- true if you want to cache query results -->
</session-factory>
</hibernate-configuration>
Of course you will need to download and reference a dll from the appropriate version of NHibernate.Caches to get the right cache provider. The memcached one takes a dependency on ICSharpCode.SharpZipLib and Memcached.ClientLibrary as well (s/b included in the download)
If you're using fluent NHibernate, there is a .Cache method in the setup chain for a session factory that you can use, though some of the properties need to be set manually through a call to .ExposeConfiguration.

NHibernate Duplicate class/entity mapping problem

I've have started my foray into C#.NET and NHibernate and I'm finally stuck on an exception I can't seem to figure out, and Google isn't helping.
I'm getting a "NHibernate.DuplicateMappingException : Duplicate class/entity mapping" on my Parent class. Below is my mapping file for the Parent class, and the Youth class that uses the Parent class:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="Surrix.Cerberus.YouthData"
namespace="Surrix.Cerberus.YouthData.Domain">
<class name="Parent">
<id name="parentId">
<generator class="guid" />
</id>
<property name="firstName" not-null="true" />
<property name="lastName" not-null="true" />
<property name="homePhone" />
<property name="parentEmail" />
<property name="relationshipToYouth" />
<!-- Address component that should map to the Address class -->
<component name="parentAddress">
<property name="street" />
<property name="state" />
<property name="zipCode" />
<property name="city" />
</component>
</class>
</hibernate-mapping>
And here is the relevant part of the Youth class (it is considerably bigger)
<set name="YouthParents" table="YouthParents" cascade="none">
<key column="youthId" />
<many-to-many column="parentId" class="Parent"/>
</set>
Only other thing is the Youth class also has the firstName and lastName properties, but I can't see that being a problem.
Make sure you are not doing both of these 2 things.
(1) adding the assembly in code:
// Code Configuration
var cfg = new Configuration();
cfg.Configure();
cfg.AddAssembly(typeof(Employee).Assembly);
// Presuming Employee resides in "MyAssembly" as seen below.
(2) And then also adding the assembly in the config file:
<!-- .config configuration -->
<session-factory>
<!-- bunch of other stuff -->
<mapping assembly="MyAssembly"/> <!-- as in MyAssembly.dll -->
</session-factory>
You are adding the file or assembly containing the mapping twice to your Configuration object.
I had this problem, and solved it by putting this statement in hibernate.cfg.xml file:
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
Another possible cause to generate this error is multiple hbm files referencing the same Assembly during a Configuration.AddAssembly.
All hbm files in the same assembly are processed with one AddAssembly call.
As it gives a duplicate class entity mapping I can only imagen that you have two or more *.xml.hbm files referring to the same .net class.
Make sure that the xml class element for your Youth class does not have the same value for the name attribute.

Categories