I have a mapping in NHibernate like this:
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping namespace="News.BusinessEntity" assembly="News.BusinessEntity" xmlns="urn:nhibernate-mapping-2.2">
<class name="News" table="News">
<property name="NewsId" type="Int64" column="NewsId" />
<property name="NewsTitle" type="String" column="NewsTitle" />
</class>
<sql-query name="Sp_News">
<return class="News" />
exec Sp_News
</sql-query>
</hibernate-mapping>
When I call session.GetNamedQuery("Sp_News") I get the following error:
Named query not known: Sp_News.
Any help would be much appreciated.
the error was solved just by setting the Build Action property of .hbm.xml file to Embeded Resource
The same error is thrown if the mapping file doesn't end with .hbm.xml.
I have accidentally renamed a mapping file and dropped the .hbm. from the name, putting it back solved this issue for me.
Related
I'm trying to map a self-referencing table with NHibernate 3.2.0.4000. However, whenever I get an instance of DomainObject, it eagerly loads the subsequent versions. I'd rather not have to put an extra column my table, though that is an option.
Can I have NHiberante not eagerly load all of the subsequent versions without maintaining the relationship on both sides?
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping assembly="NHibernateHierarchyTest" namespace="NHibernateHierarchyTest" xmlns="urn:nhibernate-mapping-2.2">
<class name="DomainObject" table="DOMAIN_OBJECT" lazy="true" >
<id name="DomainObjectId" column="DOMAIN_OBJECT_ID">
<generator class="identity" />
</id>
<property name="Property">
<column name="PROPERTY" />
</property>
<many-to-one name="PreviousVersion" class="DomainObject" >
<column name="PREVIOUS_VERSION_DOMAIN_OBJECT_ID" />
</many-to-one>
<!--<many-to-one name="SubsequentVersion" class="DomainObject">
<column name="SUBSEQUENT_VERSION_DOMAIN_OBJECT_ID" />
</many-to-one>-->
<one-to-one name="SubsequentVersion" class="DomainObject" property-ref="PreviousVersion" />
</class>
</hibernate-mapping>
The one-to-one mapping will be always loaded eagarly with NHibernate. Not sure if this is a feature or bug, but that is how it works. If you need lazy load, use many-to-one or one-to-many. Not the best answer I know, but if you can add new column...
I'm trying to get nHibernate to use second-level cache with a many-to-one relationship, however I can't find any clear explanation on how to set it up correctly. I found this How to get nhibernate to cache tables referenced via many-to-one - is my config correct?, but the example sJHonny provided is for one-to-many and it's not working for me when I adopt it. There are other posts going over this subject, but none of them are specific enough.
The XML config I provide works (I had to edit dramatically, so "hopefully" works), but lookup objects are being cached only when they are retrieved as DataObject is queried. I'd like to know 1) where/how to preload the LookupObject collection? 2) what if I assign this collection to a region and set expiration, then where/how do I reload the cache again? 3) how to change the DataObject's hbm.xml such that nHibernate doesn't generate a join with the LOOKUP table, i.e. such that lookup objects always come from the secondary cache, only getting the DATA.LOOKUP_ID from the db, not the LOOKUP.NAME?
LookupObject.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="BusinessObjects" assembly="BusinessObjects">
<class name="LookupObject" table="LOOKUP" mutable="false" batch-size="20">
<cache usage="read-only" />
<id name="Id" column="ID" />
<property name="Name" column="NAME" />
</class>
</hibernate-mapping>
DataObject.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="BusinessObjects" assembly="BusinessObjects">
<class name="DataObject"
table="DATA" mutable="false">
<composite-id>
<key-property name="Id" column="ID"/>
<key-property name="Date" column="DATE" type="Date"/>
</composite-id>
<many-to-one name="LookupObject" not-null="true" column="LOOKUP_ID" fetch="join">
</class>
</hibernate-mapping>
I believe I answered my own questions. 1) For preloading the entire collection, I just needed to change my code such that the entire list of lookups is always pulled from the DB and cached, then I get the individual object by ID with LINQ. 2) Same as before. 3) I haven't tested this yet, but I need to remove fetch="join" from many-to-one element because otherwise the SQL join will still be generated and data will be still returned. Then set the lookup object without nHibernate by getting it from cache.
I have the following mapping file:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="Project1.Accounts"
namespace="Project1.Core.Domain">
<class name="Equipment" table="Equipment">
<id name="ID" column="ID">
<generator class="identity"></generator>
</id>
<property name="Name" />
<property name="Description" />
<property name="AccountID" />
<property name="EquipmentTypeID" />
<many-to-one name="Account" class="Project2.Core.Domain.Account, Project2.Core" column="AccountID"/>
<many-to-one name="EquipmentType" class="Insight.IT.Accounts.Core.Domain.EquipmentType, Insight.IT.Accounts" column="EquipmentTypeID"/>
</class>
</hibernate-mapping>
I'm getting the following error:
NHibernate.MappingException: An association from the table Equipment refers to an unmapped class: Project2.Domain.Account
Just to be clear - The Account class lives in a different assembly than the Equipment class does. The project that the Account class resides in has it's own hibernate.cfg.xml.
Basically, it looks like i need a way to reference multiple mapping assemblies in the hibernate.cfg.xml file. Is this possible??
You can do it like this:
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="dialect">...</property>
<property name="connection.driver_class">...</property>
...
<mapping assembly="MyProject.OtherAssembly"/>
</session-factory>
</hibernate-configuration>
It is possible, you'll just have to indicate this in your mapping file (and it looks like you did this).
Did you add both the assemblies to the NHibernate configuration, before creating the sessionfactory ?
Thanks for the responses. Actually, I ended up doing it a little different. I just removed the tag from the hibernate.cfg and used fully qualified names in the .hbm.xml files. Thanks!!
I have what appears to be a simple mapping problem in NHibernate, however I have been struggling to find a solution to the problem for a number of days now, and would appreciate some assistance. I am using VB.NET under VS2005. My VS2005 solution structure is as follows:
Solution: PsalertsIP
Project (Assembly): Core
Folder Data (Namespace PsalertsIp.Core.Data)
Contains Interfaces for communication with repository classes
example: PsalertsEventRepo Implements IPsalertsEventRepo
Folder Domain (Namespace PsalertsIP.Core.Domain)
Contains all POCO domain objects and related interfaces
example: PsalertsEvent Implements IPsalertsEvent
Also underneath the assembly 'Core' are the NHibernate config file and the mapping file for the PsalertsEvent class, which is as follows:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="Core"
namespace="Core.Domain">
<class name="PsalertsEvent" table="Source_table" lazy="true">
<id name="Id" column="Id" type="long" unsaved-value="0"
access="field.camelcase-underscore">
<generator class="native" >
<param name="sequence">My_Oracle_Sequence</param>
</generator>
</id>
<property name="Substation" column="Field1" />
<property name="BusbarId" column="Field2" />
<property name="PlantId" column="Field3" />
<property name="AlarmName" column="Field4" />
<property name="AlarmStatus" column="Field5" />
<property name="EventTime" column="Field6" />
</class>
</hibernate-mapping>
When I attempt to carry out a simple test of the NHibernate environment through NUnit (appreciate that this isn't unit testing, however needed a simple vehicle to test the NHibernate setup), the test fails, and I observe the following output in NUnit:
PsalertsIp.Tests.Data.PSALERTSEventRepoTests (TestFixtureSetUp):
System.TypeInitializationException : The type initializer for 'Nested' threw an exception.
----> NHibernate.MappingException : Could not compile the mapping document: PsalertsEvent.hbm.xml
----> NHibernate.MappingException : persistent class Core.Domain.PsalertsEvent, Core not found
----> System.TypeLoadException : Could not load type 'Core.Domain.PsalertsEvent' from assembly 'Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
I suspect that the problem may be to do with the structure of the solution in VS2005, however I have tested multiple different assembly/namespace permutations to no avail.
I think you need to change the namespace attribute on the hibernate-mapping element to "PsalertsIP.Core.Domain" (as you've specified above).
Also ensure the assembly attribute on the hibernate-mapping element specifies the full assembly name of your project (right-click project -> Properties -> Application tab).
hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="Core"
namespace="PsalertsIP.Core.Domain">
I have an application that has a core assembly with base classes that I need to inherit from.. I need to save these to the database and after reading about NHibernate decided to use it.
However I have a problem with one of my new inherited classes.. I have setup the subclass map but when I save, it neither attempts to save any of it's base class properties or any of it's new ones that I have assigned in the mapping!
My classes are laid out like the following: (from a small demo app)
core assemblies
DataItem -> User
Anything that will touch the database inherits the DataItem class as it handles the id, modified date etc etc..
In my test I setup user to only have a FirstName..
If I save a new User it works great.. however when I inherit from user and then add another property called LastName and attempt to save this new object.. it only puts a sql statement together of INSERT INTO t_User (id) VALUES(?).. it doesn't attempt to save the first name or last name.. either though both have been set and are mapped.
My nhibernate.config:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory name="DAL">
<property name="dialect">NHibernate.Dialect.MsSql2005Dialect</property>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
<property name="adonet.batch_size">16</property>
<property name="current_session_context_class">web</property>
<property name="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
<mapping assembly="DAL"/>
<mapping assembly="NHibernateDemo"/>
</session-factory>
</hibernate-configuration>
As you can see I have 2 assemblies.. my DAL is my core and the NHibernateDemo is a web application that uses the core for inheritance.
My core DataItem mapping:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="DAL" namespace="DAL.Model">
<class name="DataItem" table="t_DataItem" >
<id name="Id">
<generator class="native" />
</id>
<discriminator column="typeid" type="System.Int32"></discriminator>
<property name="IsActive" column="isActive" not-null="true" />
<property name="TypeId" column="typeId" not-null="true"></property>
<many-to-one name="Parent" column="ParentId" class="DataItem"></many-to-one>
<bag name="Children" cascade="all-delete-orphan">
<key column="ParentId"></key>
<one-to-many class="DataItem"/>
</bag>
<joined-subclass name="User" table="t_Users">
<key column="id"></key>
<property name="FirstName" column="firstName" not-null="true" ></property>
</joined-subclass>
<joined-subclass name="Email" table="t_Emails">
<key column="emailid"></key>
<property name="Address" column="Address"></property>
</joined-subclass>
</class>
</hibernate-mapping>
My inherited NewUser mapping that doesn't work!:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernateDemo" namespace="NHibernateDemo.Model">
<subclass name="NewUser" extends="DAL.Model.User, DAL" discriminator-value="1">
<property name="LastName" column="LastName"></property>
</subclass>
Why is it that when I attempt to save my class NewUser that it doesn't attempt to save any of the other properties set, whether from it's base or newly declared properties?
I'd really appreciate any help or insight to this.. I must be missing something really simple and I just can't see it.
Thanks,
Mike
It could be that you're not able to mix subclass and joined-subclass mappings in the same class hierarchy. Since your DataItem and User are related by joined-subclass, you may need to make your NewUser class another joined-subclass of User.
Another issue might be the use of the "discriminator" in your current NewUser mapping. The discriminator should be an additional column in your User table that NHibernate uses to tell the difference between a User record and a NewUser record. I'm not sure if this works where the User base class might not specify its discriminator value, whereas the NewUser does. I'm not sure if you're specifying the discriminator-column anywhere, which might also be a problem.
I would suggest first trying to make NewUser a joined-subclass of User.