NHibernate.MappingException: No persister No mapped documents found in assembly - nhibernate

I have been doing nhibernate since many days. But Today I stuck at a frustrating issue i.e. mapping exception.
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="IPC.Base.Domains" assembly="IPC">
<class name="MenuItem" table="dbo.COR_MenuItem" default-access="property" default-cascade="save-update" default-lazy="true">
<cache usage="read-only" region="completelyStatic"/>
<id name="Id" type="System.Int32">
<generator class="identity" />
</id>
<property name="Name" type="System.String" />
<property name="Order" column="DisplayOrder" />
<property name="Key" column="KeyChain" />
<property name="Route" />
<property name="ActionMethod" />
<property name="IsHotlink" />
<many-to-one name="ParentMenuItem" column="ParentMenuItemId" class="MenuItem" cascade="none"/>
<bag name="MenuItems" table="dbo.COR_MenuItem" cascade="none">
<cache usage="read-only" region="completelyStatic"/>
<key column="ParentMenuItemId" />
<one-to-many class="MenuItem" />
</bag>
</class>
</hibernate-mapping>
And I do have a mapping class as following:
using System;
using System.Collections.Generic;
namespace IPC.Base.Domain
{
public partial class MenuItem : PersistentObject
{
public MenuItem()
{
MenuItems = new List<MenuItem>();
}
public virtual string Name { get; set; }
public virtual int? Order { get; set; }
public virtual string Key { get; set; }
public virtual string Route { get; set; }
public virtual string ActionMethod { get; set; }
public virtual bool IsHotlink { get; set; }
public virtual IList<MenuItem> MenuItems { get; set; }
public virtual MenuItem ParentMenuItem { get; set; }
/// <summary>
/// only to be used from the menu builder app
/// </summary>
/// <param name="id"></param>
public virtual void SetId(int id)
{
Id = id;
}
}
}
I have the following nHibernate Config running with the application. But as per my experience there is absolutely no issue with the nHibernate Config.
<?xml version="1.0"?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory name="IPC">
<property name="dialect">NHibernate.Dialect.MsSql2005Dialect</property>
<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
<property name="connection.connection_string">**************SQL CONNECTION****************/property>
<property name="proxyfactory.factory_class">NHibernate.ByteCode.LinFu.ProxyFactoryFactory, NHibernate.ByteCode.LinFu</property>
<property name="cache.provider_class">NHibernate.Caches.SysCache.SysCacheProvider, NHibernate.Caches.SysCache</property>
<property name="cache.use_query_cache">true</property>
<property name="show_sql">true</property>
<mapping assembly="IPC"/>
</session-factory>
</hibernate-configuration>
I am using the following line for code for invoking nHibernate session object to system.
static ISessionFactory CurrentFactory
{
get
{
if (factory == null)
{
Configuration cfg = new Configuration();
if (cfgFile == null)
cfg = cfg.Configure();
else
cfg = cfg.Configure(cfgFile);
factory = cfg.BuildSessionFactory();
}
return factory;
}
}
public static ISession Create()
{
var session = CurrentFactory.OpenSession();
return session;
}
Now! When I call the following line of code I am getting:
public virtual T Get(int id)
{
return Session.Get<T>(id);
}
No persister for: IPC.Base.Domain.MenuItem
Exception Details: NHibernate.MappingException: No persister for: IPC.Base.Domain.MenuItem
I have already enabled by nHibernate log. Following are the basic details from log
00:54:40.011 [4] INFO NHibernate.Cfg.Environment - NHibernate 2.1.0.4000 (2.1.0.4000)
00:54:40.055 [4] INFO NHibernate.Cfg.Environment - Bytecode provider name : lcg
00:54:40.057 [4] INFO NHibernate.Cfg.Environment - Using reflection optimizer
00:54:40.682 [4] DEBUG NHibernate.Cfg.Configuration - dialect=NHibernate.Dialect.MsSql2005Dialect
00:54:40.683 [4] DEBUG NHibernate.Cfg.Configuration - connection.driver_class=NHibernate.Driver.SqlClientDriver
00:54:40.683 [4] DEBUG NHibernate.Cfg.Configuration - connection.connection_string=*********************SQL Connection*****************
00:54:40.683 [4] DEBUG NHibernate.Cfg.Configuration - proxyfactory.factory_class=NHibernate.ByteCode.LinFu.ProxyFactoryFactory, NHibernate.ByteCode.LinFu
00:54:40.683 [4] DEBUG NHibernate.Cfg.Configuration - cache.provider_class=NHibernate.Caches.SysCache.SysCacheProvider, NHibernate.Caches.SysCache
00:54:40.683 [4] DEBUG NHibernate.Cfg.Configuration - cache.use_query_cache=true
00:54:40.683 [4] DEBUG NHibernate.Cfg.Configuration - show_sql=true
00:54:40.684 [4] DEBUG NHibernate.Cfg.Configuration - IPC<-IPC
00:54:40.685 [4] INFO NHibernate.Cfg.Configuration - Searching for mapped documents in assembly: IPC
00:54:40.689 [4] WARN NHibernate.Cfg.Configuration - No mapped documents found in assembly: IPC, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
00:54:40.691 [4] INFO NHibernate.Cfg.Configuration - Configured SessionFactory: IPC
00:54:40.691 [4] DEBUG NHibernate.Cfg.Configuration - properties: System.Collections.Generic.Dictionary`2[System.String,System.String]
00:54:45.716 [4] INFO NHibernate.Cfg.Configuration - checking mappings queue
00:54:45.716 [4] INFO NHibernate.Cfg.Configuration - processing one-to-many association mappings
00:54:45.717 [4] INFO NHibernate.Cfg.Configuration - processing one-to-one association property references
00:54:45.717 [4] INFO NHibernate.Cfg.Configuration - processing foreign key constraints
00:54:45.747 [4] INFO NHibernate.Dialect.Dialect - Using dialect: NHibernate.Dialect.MsSql2005Dialect
I have read almost all the post with stack! :) and even doing google for the same. The final words I am getting there is an issue with my assembly naming! I sure that there is a issue with the steps which I have followed. But still searching for that trigger!!!
Thanks!
In advance!!

Probably you forgot to set your hbm mappings as embedded resource to the DLL.

Finally I resolved the issue! Its basically a stupid stuff which normally I tend to do and then forget to get it back on running stage.
Yes, I was related with the assembly issue. Nothing but when I was trying to build then data layer application It was not enbading the xml files inside assembly.
A Fix for solve the problem go to your
*.hbm.xml files and do a right click and change build option of that file
to embedded resource.
Alrite!
Many thanks!

Related

NHibernateHelper - many tables

I am new in NHibernate, I have based on tutorial: http://nhibernate.info/doc/tutorials/first-nh-app/your-first-nhibernate-based-application.html . So I have NHibernateHelper:
public class NHibernateHelper {
private static ISessionFactory _sessionFactory;
private static ISessionFactory SessionFactory
{
get
{
if (_sessionFactory == null)
{
var configuration = new Configuration();
configuration.Configure();
configuration.AddAssembly(typeof (Product).Assembly);
_sessionFactory = configuration.BuildSessionFactory();
}
return _sessionFactory;
}
}
public static ISession OpenSession()
{
return SessionFactory.OpenSession();
} }
But I have also entity Category and User? Do I need each entity add to configuration using code AddAssembly?? Because when I have added code:
configuration.AddAssembly(typeof (Product).Assembly);
configuration.AddAssembly(typeof(Category).Assembly);
I have error:
Could not compile the mapping document: MvcApplication1.Mappings.Product.hbm.xml
First check whether you have set the "Build Action" of all the mapping files (*.hbm.xml) to "Embedded Resource". This is VERY important.
Then you only need to add a call to AddAssembly once as NHibernate is clever enough to scan through the assembly to sniff out all your entities that map to all your embedded hbm.xml files..
e.g. You only need to supply the assembly once that contains all your entities:-
_configuration.AddAssembly(typeof (Product).Assembly);
NHibernate will now find Category (and all others) automatically as long as they are in the same assembly as Product. HTH
you can alternatively add the mapping tag into the web.config, instead of adding it in code on the SessionFactory initialization. Then, your code will look like this:
if (_sessionFactory == null)
{
var configuration = new Configuration();
configuration.Configure();
_sessionFactory = configuration.BuildSessionFactory();
}
And in the web config you will have to indicate the assembly where all of your mappings are, like this:
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="connection.provider">
NHibernate.Connection.DriverConnectionProvider
</property>
<property name="dialect">
NHibernate.Dialect.MsSql2005Dialect
</property>
<property name="connection.driver_class">
NHibernate.Driver.SqlClientDriver
</property>
<property name="connection.connection_string">
-- YOUR STRING CONNECTION --
</property>
<property name="proxyfactory.factory_class">
NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle
</property>
<mapping assembly="You.Assembly.Namespace" />
</session-factory>
Being the important configuration tag "mapping assembly="Your.Assembly.Namespace". As the other contributor mentioned before, it is very important that you mark each of the hbm.xml file as embedded resource, otherwise it will be as you never created it. By doing this, you just need to create all of the mappings inside of this assembly (project) and those will be automatically read when NH configures.

arquillian-glassfish-embedded-3.1 1.0.0.CR3 configuring JDBC datasource

I was trying to use arquillian-glassfish-embedded-3.1 container to test and EJB3 application. I was trying to figure out how to set up a simple JDBC datasource that could be injected as a resource to a Stateless ejb.
Here is what I have :
#Stateless
public class HelloEJBBean implements HelloEJB {
#Resource(name="myDataSource")
private DataSource datasource;
public String sayHelloEJB(String name) {
return "Hello " + name;
}
}
also have arquillian.xml with the following content:
<?xml version="1.0"?>
<arquillian xmlns="http://jboss.com/arquillian"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:glassfish="urn:arq:org.jboss.arquillian.container.glassfish.embedded_3">
<glassfish:container>
<glassfish:bindHttpPort>9090</glassfish:bindHttpPort>
<glassfish:instanceRoot>src/test/resources</glassfish:instanceRoot>
<glassfish:autoDelete>false</glassfish:autoDelete>
</glassfish:container>
</arquillian>
and a domain.xml with
<domain>
<applications />
<resources>
<jdbc-resource pool-name="ArquillianEmbeddedOraclePool" jndi-name="myDataSource"
object-type="user" enabled="true"/>
<jdbc-connection-pool name="ArquillianEmbeddedOraclePool" res-type="javax.sql.DataSource"
datasource-classname="oracle.jdbc.driver.OracleDriver">
<property name="user" value="user"/>
<property name="password" value="password"/>
<property name="serverName" value="servername"/>
<property name="DatabaseName" value="dbname"/>
<property name="url" value="jdbc:oracle:thin:#servername:1521/dbname"/>
</jdbc-connection-pool>
</resources>
</domain>
and the simple test looks like this:
#RunWith(Arquillian.class)
public class HelloEJBTest {
#Deployment
public static JavaArchive createTestArchive() {
return ShrinkWrap.create(JavaArchive.class, "helloEJB.jar")
.addClasses(HelloEJB.class, HelloEJBBean.class);
}
#EJB
private HelloEJB helloEJB;
#Test
public void testHelloEJB() {
String result = helloEJB.sayHelloEJB("Michael");
assertEquals("Hello Michael", result);
}
}
I get the following error:
... 108 more
Caused by: com.sun.enterprise.container.common.spi.util.InjectionException: Exception attempting to inject Res-Ref-Env-Property: myDataSource#javax.sql.DataSource# resolved as: jndi: myDataSource#res principal: null#mail: null
No Runtime properties
... 108 more
Caused by: com.sun.enterprise.container.common.spi.util.InjectionException: Exception attempting to inject Res-Ref-Env-Property: myDataSource#javax.sql.DataSource# resolved as: jndi: myDataSource#res principal: null#mail: null
No Runtime properties
Any help is appreciated.
Thanks

NHibernate Mapping Exception: invalid child element

I'm having a problem with NHibernate and the mapping file when I try to save my drink object in my MVC application. My mapping file is an embedded resource and my hibernate.cfg.xml is copy always.
Here are my class.cs:
namespace FrancosPoS.DBMapping {
public class drink {
public drink() { }
public virtual int id { get; set; }
public virtual string type { get; set; }
public virtual string price { get; set; }
}
}
My XML mapping:
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping assembly="FrancosPoS.DBMapping" namespace="FrancosPoS.DBMapping" xmlns="urn:nhibernate-mapping-2.2">
<class name="drink" table="drink" lazy="true" >
<id name="id">
<generator class="identity" />
<column name="id" sql-type="int(11)" not-null="true" />
</id>
<property name="type">
<column name="type" sql-type="varchar(25)" not-null="true" />
</property>
<property name="price">
<column name="price" sql-type="varchar(8)" not-null="true" />
</property>
</class>
</hibernate-mapping>
By the way, the connection opens and close fine if I don't try to save it on the database.
Here is my Solution Explorer:
Solution Explorer Image
And here is the error that is driving me nuts:
"Error: NHibernate.MappingException: FrancosPoS.DBMapping.drink.hbm.xml(6,8): XML validation error: The element 'id' in namespace 'urn:nhibernate-mapping-2.2' has invalid child element 'column' in namespace 'urn:nhibernate-mapping-2.2'. ---> System.Xml.Schema.XmlSchemaValidationException: The element 'id' in namespace 'urn:nhibernate-mapping-2.2' has invalid child element 'column' in namespace 'urn:nhibernate-mapping-2.2'.\r\n --- End of inner exception stack trace ---
the problem is in node id, it does not have a child, remove that node and it will simply be like this:
<id name="id">
<generator class="identity" />
</id>
the column's name is specified in id node, and you dont have to tell column has "not-null" constraint since id columns are always required
Also, in this line of your xml mapping:
<hibernate-mapping assembly="FrancosPoS.DBMapping" namespace="FrancosPoS.DBMapping" xmlns="urn:nhibernate-mapping-2.2">
"assembly" attribute seems to be wrong, it should be the name of your assembly (which i'm almost sure is "FrancosPos").

How to configure RetryAdvice and ExceptionTranslation for Deadlocks using NHibernate and Spring

i am using Spring.net 1.2 with NHibernate 2.0.1.
Within my project i'am facing some Deadlock issues and besides the database tweaks to minimize the occurence i would like to implement Springs RetryAdvice to handle this.
I can't find any working example how to configure a this. The reference seems to be clear about how to use it but somehow i can't get it working.
<!--Used to translate NHibernate exception to Spring.DataAccessExceptions-->
<object type="Spring.Dao.Attributes.PersistenceExceptionTranslationPostProcessor, Spring.Data"/>
<!--ExceptionHandler performing Retry on Deadlocks-->
<object name="ExceptionHandlingAdvice" type="Spring.Aspects.RetryAdvice, Spring.Aop">
<property name="retryExpression" value="on exception name DeadLockLoserException retry 3x rate (1*#n + 0.5)"/>
</object>
I have added the [Repository] attribute to my DAOs to get ExceptionTranslation enabled and tried to add the RetryAdvice to the TransactionProxyFactoryObject i am using but it won't work. I don't understand where to put this Advice. Do i have to declare a PointCut to add it or how could i get it to work as expected.
Thx in advance - any help appreciated.
After 1 and a half month of waiting for someone solving my problem i finally found time to elaborate the solution for this by myself. In fact it wasn't that difficult i thought it was. Maybe thats why i wasn't able to find any good example.
So here we go: The following test will show the usage:
Configuration: (SessionFactory and TransactionManager etc. omitted for brevity)
<!-- Retries the Tx after DeadlockExceptions -->
<object name="ExceptionHandlingAdvice" type="Spring.Aspects.RetryAdvice, Spring.Aop">
<property name="retryExpression" value="on exception name DeadlockLoserDataAccessException retry 3x delay 1s"/>
</object>
<!--A Transaction-Configuration for our DAO-MOCK-->
<object id="TxProxyConfigurationTemplate" abstract="true" type="Spring.Transaction.Interceptor.TransactionProxyFactoryObject, Spring.Data">
<property name="PlatformTransactionManager" ref="HibernateTransactionManager"/>
<property name="TransactionAttributes">
<name-values>
<add key="ThrowDeadLock*" value="PROPAGATION_REQUIRED"/>
</name-values>
</property>
</object>
<object id="MockDaoTxPFO" parent="TxProxyConfigurationTemplate">
<property name="Target" ref="MockDao"/>
</object>
<!--The ProxyFactoryObject based on the DAO-Mock interface-->
<object id="MockDao" type="Spring.Aop.Framework.ProxyFactoryObject, Spring.Aop" >
<property name="proxyInterfaces" value="RetryAdvice.IDaoMock"/>
<property name="target" ref="MockDaoImpl"/>
<property name="interceptorNames">
<list>
<value>ExceptionHandlingAdvice</value>
</list>
</property>
</object>
<!--Mocked DAO Implementation -->
<object id="MockDaoImpl" type="RetryAdvice.DaoMock, RetryAdvice">
<constructor-arg name="maxExceptionCount" value="2" />
</object>
Mocked Dao: This DAO will throw DeadLockLooserExceptions twice and then pass.
public interface IDaoMock
{
void ThrowDeadLock();
int MethodCallCount { get; }
}
[Repository]
public class DaoMock : IDaoMock
{
private int maxExceptionCount;
public int MethodCallCount { get; private set; }
public DaoMock(int maxExceptionCount)
{
this.maxExceptionCount = maxExceptionCount;
}
public void ThrowDeadLock()
{
MethodCallCount++;
if (MethodCallCount <= maxExceptionCount)
{
throw new DeadlockLoserDataAccessException("FAKE", new HibernateException("This is a fake Exception.", null));
}
}
The Test:
[Test]
public void RetryAdviceTest()
{
IDaoMock mockDao = (IDaoMock)this.appContext.GetObject("MockDaoTxPFO");
mockDao.ThrowDeadLock();
Assert.That(mockDao.MethodCallCount, Is.EqualTo(3));
}
Any hints or remarks appreciated.

NHibernate Cascade none still updating related entity

I am then using Fluent NHibernate and its automapping feature to map the the following simplified POCO classes:
public class Webpage
{
public virtual int Id { get; set; }
public virtual string UrlIdentifier { get; set; }
public virtual WebpageType WebpageType { get; set; }
}
public class WebpageType
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
}
I am then overriding the following mapping to explicitly set no cascading from Webpage to WebpageType:
public class WebpageMap : IAutoMappingOverride<Webpage>
{
public void Override(AutoMapping<Webpage> mapping)
{
mapping.References(w => w.WebpageType).Cascade.None();
}
}
For any pur NHibernate readers, here are the xml mappings produced by fluent:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property" auto-import="true" default-cascade="none" default-lazy="true">
<class xmlns="urn:nhibernate-mapping-2.2" name="EveryPage.Core.Domain.Webpage, EveryPage.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`Webpage`">
<id name="Id" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" unsaved-value="0">
<column name="Id" />
<generator class="identity" />
</id>
<property name="UrlIdentifier" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="UrlIdentifier" />
</property>
<many-to-one cascade="none" class="EveryPage.Core.Domain.WebpageType, EveryPage.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="WebpageType">
<column name="WebpageType_id" />
</many-to-one>
</class>
</hibernate-mapping>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property" auto-import="true" default-cascade="none" default-lazy="true">
<class xmlns="urn:nhibernate-mapping-2.2" name="EveryPage.Core.Domain.WebpageType, EveryPage.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`WebpageType`">
<id name="Id" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" unsaved-value="0">
<column name="Id" />
<generator class="identity" />
</id>
<property name="Name" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Name" />
</property>
</class>
</hibernate-mapping>
The problem comes when I test that updates do not cascade to WebpageType via webpage, basically they do!!
I have the following test:
[Test]
public void Assert_SaveOrUpdate_On_Webpage_Does_Not_Cascade_Update_To_WebpageType()
{
// Get the existing webpage.
webpage = _webpageRepository.Get("~/testwebpage1.aspx");
// Update the WebpageType.
const string webpageTypeName = "qwerty test";
webpage.WebpageType.Name = webpageTypeName;
// Save the changes.
Assert.DoesNotThrow(() => _webpageRepository.SaveOrUpdate(webpage));
// We need to flush the changes to the store for it to execute the changes.
Assert.DoesNotThrow(() => NHibernateSession.Current.Flush());
// Remove the webpage and tag from the level 1 cache so we force a trip to the store on our next check.
NHibernateSession.Current.Evict(webpage);
// Check that the webpageType has not been updated.
webpageType = _webpageTypeRepository.Get(webpageType.Id);
Assert.AreNotEqual(webpageTypeName, webpageType.Name);
}
The above test is wrapped in a global transaction.
The test fails and NHibernate does execute an update to the Name of the related WebpageType. The delete and save(create new) cascades work correctly and do not cascade.
Have I missunderstood cascade and/or is there a problem with my logic/test.
Any help/advice is appreciated. Thanks.
If you are trying to stop your app from accidentally changing properties on WebPageType, I think it would be easier and safer to achieve this by marking WebPageType as ReadOnly in the mapping. Then you won't need to protect it via handling cascading in all its associations.
I think this is a misunderstanding of what cascading means.
In your example, NHibernate will update the Name property of you WebPageType no matter what you set cascading to. If you think about it, how would the NHibernate library tell if you're manipulating the property's value using the association from the WebPage instance, or if it's done "directly"?
The settings for cascading in NHibernate tells how associations between entities should be handled, not how the actual value inside each entity is handled. For example, you can set delete cascading, which will automatically delete associated entities when the entity itself is deleted.
Things blog post might make things a bit clearer, or at least work as some kind of reference: http://ayende.com/Blog/archive/2006/12/02/NHibernateCascadesTheDifferentBetweenAllAlldeleteorphansAndSaveupdate.aspx
What does your repository do? Make sure it doesn't run a saveorupdate on the webpagetype. If it isn't then I don't see any obvious explanation for this behaviour.