I'm new to nhibernate and tried a few tutorials but none of them helped with that problem:
I did my mappings, classes, ... and when I'm trying to add my class to configuration, hibernate is searching for the wrong filename (I guess in the wrong directory).
This is my hibernate.cfg.xml:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" />
</configSections>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
<property name="connection.connection_string">Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-WebApplication2-20170915093558.mdf;Initial Catalog=aspnet-WebApplication2-20170915093558;Integrated Security=True</property>
<property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
<mapping assembly="WebApplication1"/>
</session-factory>
</hibernate-configuration>
</configuration>
This is my Test-entity:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="WebApplication1"
namespace="WebApplication1.Domain">
<class name="Test" table="Test" lazy="false">
<id name="Id">
<generator class="native" />
</id>
<property name="Name" />
<property name="DatasetCreationDate" />
</class>
</hibernate-mapping>
namespace WebApplication1.Domain
{
public class Test
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual DateTime DatasetCreationDate { get; set; }
}
}
This is the code I'm now calling:
Configuration configuration = new Configuration();
configuration.AddAssembly(Assembly.GetCallingAssembly());
configuration.AddClass(typeof(Test));
configuration.Configure();
SessionFactory = configuration.BuildSessionFactory();
On this line I get following error by nhibernate:
configuration.AddClass(typeof(Test));
Resource not found: WebApplication1.Domain.Test.hbm.xml
This is my structure:
Any idea what is going wrong here? I think my file-structure is also wrong.
So I found the problems myself (with a bit of help by Radim Köhler):
1st problem
The properties for the .hbm.xml-files
Build Action: Embedded Resource.
Copy to Output Directory: Do not copy
2nd problem
I was adding the assembly twice.
Once in the hibernate.cfg.xml: <mapping assembly="WebApplication1"/>
and once when building the session factory: configuration.AddAssembly(Assembly.GetCallingAssembly());
I now deleted the one in the hibernate.cfg.xml
Related
I'm having an issue where I'm sending a message to nServiceBus with a message data field of variable length. nServiceBus is using nHibernate to create a table called
[NServiceBus].[PendingMentorEmailSagaData]
from a class called PendingMentorEmailSagaData . The message field is however getting set to nvarchar(255), I am looking for a way to have it set to nvarchar(MAX).
I've tried using an embedded hbm file, but am getting a "persistent class PendingMentorEmailSagaData not found" error.
This probably means I can't figure out what class to set the file too.
The hbm file:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="PendingMentorEmailSagaData">
<id name="Id" />
<property name="OriginalMessageId" />
<property name="Originator" />
<property name="PendingMentorEmailCommandId" />
<property name="JobBoardCode" />
</class>
</hibernate-mapping>
PendingMentorEmailSagaData is the name of the saga's data class.
Create a PendingMentorEmailSagaData.hbm.xml file in the same project that the saga exists on, eg:
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:nhibernate-mapping-2.2">
<class name="MY_NAMESPACE.PendingMentorEmailSagaData, MY_ASSEMBLY_NAME" table="PendingMentorEmailSagaData" dynamic-update="true" optimistic-lock="all">
<id name="Id" type="Guid">
<generator class="assigned" />
</id>
<property name="Originator" />
<property name="OriginalMessageId" />
<property name="LargeText" type="StringClob" />
</class>
</hibernate-mapping>
2. Mark that file as an Embedded Resource
I have an issue with a two subclasses using the same table and same fields. Even though the generated table has this fields as nullable uniqueidentifiers, when I save the one record that does not use the third column, then the created field has a value of "000000000-0000-0000-0000-000000000000" instead of NULL. Other parts of application require this place to be null. Here's the code. What's wrong?
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly=".."
namespace="...">
<class name="TEST" table="..." discriminator-value="not null">
<id name="Id" column="tID">
<generator class="assigned" />
</id>
<discriminator column="iTestTypeID" type="Int32" not-null="true"/>
<property name="TotalScore" column="fTotalScore"/>
<property name="IsTimedOut" column="bTimedOut"/>
</hibernate-mapping>
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly=".."
namespace="...">
<subclass name="TestA" extends="TEST" discriminator-value="3">
<many-to-one name="Department" column="uTestCriteria01" cascade="save-update" not-null="false" />
<many-to-one name="Building" column="uTestCriteria02" cascade="save-update" not-null="false" />
</subclass>
</hibernate-mapping>
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly=".."
namespace="...">
<subclass name="TestB" extends="TEST" discriminator-value="3">
<many-to-one name="Building" column="uTestCriteria01" cascade="save-update" not-null="false" />
<many-to-one name="Floor" column="uTestCriteria02" cascade="save-update" not-null="false" />
<many-to-one name="Room" column="uTestCriteria03" cascade="save-update" not-null="false" />
</subclass>
</hibernate-mapping>
My guess would be that your objects aren't using nullable types.
Do you have the types defined like this:
public class A
{
public Guid? field { get; set; }
}
Take a look at this StackOverflow article for an explanation:
How can I default a parameter to Guid.Empty in C#?
Also in your question I would list the specific field(s) you are talking about so there is no confusion and post the code for your objects that are tied to this mapping.
I have looked around quite a bit and found many examples on how to map children, but I am missing something. I cannot get the follwing mapping to work
Table 1:
ORDERID RAW No
HISTORYID RAW No
Mapping:
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping auto-import="false" xmlns="urn:nhibernate-mapping-2.2">
<class name="Order" lazy="false" table="Orders" polymorphism="explicit" dynamic-insert="true">
<id name="OrderId" column="OrderId" type="Guid">
<generator class="GuidGenerator" />
</id>
<bag name="OrderHistoryBag" lazy="false" table="OrderHistory" cascade="none">
<key column="HistoryId" />
<one-to-many class="OrderHistory" not-found="ignore" />
</bag>
</class>
</hibernate-mapping>
Class Properties:
public virtual IList<OrderHistory> OrderHistoryBag { get; set; }
public virtual Collection<OrderHistory> OrderHistory { get; set; }
Table 2:
HISTORYSEQ NUMBER(6,0) No
HISTORYID RAW Yes
Mapping:
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="OrderHistory" lazy="false" table="OrderHistory" polymorphism="explicit">
<id name="HistorySequence" column="HistorySeq" type="Int32">
<generator class="sequence">
<param name="sequence">S_Hist</param>
</generator>
</id>
<many-to-one name="Order" class="Order" column="HistoryId" not-null="true" cascade="none" lazy="false" />
</class>
</hibernate-mapping>
Class Property:
public virtual Order Order { get; set; }
Everything compiles and runs fine except that the OrderHistoryBag and its assocaiated OrderHistorycollection are always an empty collection.
I guess the short story is that I'm trying to map HistoryId in the parent class to HistoryId in the child class neither of which are primary keys on the entities.
My NHibernate assemblies are v1.2.1.400 (Don't ask).
you need to specify the property which is used to join to the historyItems using property-ref
<property name="HistoryId" />
<bag name="OrderHistoryBag" lazy="false" table="OrderHistory" cascade="none">
<key column="HistoryId" property-ref="HistoryId"/>
<one-to-many class="OrderHistory" not-found="ignore" />
</bag>
I am using Visual Studio 2010 with NHibernate 3.2.0.GA, I do have a web application with the following Web.Config File:
<?xml version="1.0"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>
<configSections>
<section name="hibernate-configuration"
type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate"/>
</configSections>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory name ="Nhibernate.Test">
<property name="connection.driver_class">
NHibernate.Driver.SqlClientDriver</property>
<property name="connection.connection_string">
Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Users\Mahshid\Desktop\BugTracker\BugTracker\App_Data\BugTrackerDB.mdf;
Integrated Security=True;User Instance=True
</property>
<property name ="adonet.batch_size">10</property>
<property name="show_sql">true</property>
<property name="dialect">Nhibernate.Dialect.MsSql2008Dialect</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.LinFu.ProxyFactoryFactory,
NHiberante.ByteCode.LinFu</property>
</session-factory>
</hibernate-configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
</configuration>
I added my sql database as a local one inside vs2010, I also do have two nhibernate hbm.xml files with as follows:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
namespace="BugTracker.Model"
assembly ="BugTracker">
<class name="Bug" table ="Bugs" lazy="false">
<id name ="BugId" column ="BugId" type="int"
unsaved-value="0">
<generator class="native"/>
</id>
<property name="Desc" column="Description"/>
<property name="Fixed" column ="Fixed"/>
<many-to-one name="Application"
class="Application"
column="ApplicationId"
cascade="all"
not-null="true"/>
</class>
</hibernate-mapping>
And:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="BugTracker.Model"
assembly="BugTracker">
<class name="Application" table="Applications" lazy="false">
<id name="ApplicationId" column ="ApplicationId" type="int" unsaved-value ="0">
<generator class ="native"></generator>
</id>
<property name ="Name" column="Name"/>
<component access ="field.camelcase-underscore" name ="Developer"
class="Developer">
<property access ="field.camelcase-underscore"
column ="DeveloperFirstName" name="FirstName"/>
<property access ="field.camelcase-underscore"
column="DeveloperLastName" name="LastName"/>
</component>
<bag cascade="all-delete-orphan"
inverse ="true"
name ="Bugs"
lazy="false"
access ="field.camelcase-underscore">
<key column ="ApplicationId"/>
<one-to-many class ="Bug"/>
</bag>
</class>
</hibernate-mapping>
I set them as embedded resource, believe me but I get the exception in the following code part:
private static void Init()
{
NHibernate.Cfg.Configuration config;
config = new NHibernate.Cfg.Configuration();
config.AddAssembly("BugTracker");
config.Configure();
_SessionFactory = config.BuildSessionFactory();
}
With this message:
Could not compile the mapping document: BugTracker.Model.Bug.hbm.xml
Inner Exception Message:
Could not instantiate dialect class Nhibernate.Dialect.MsSql2008Dialect
I know that this is beginer's issue but i am just a newbie! but i appreciate your ideas...
Shouldn't the name of dialect be NHibernate.Dialect.MsSql2008Dialect? I mean H must be capital?
I have a program with a base class (Message) from which many other classes derivate (notably Article and Comment). I would like to create a criteria that will select all the Comments for which the RootMessage property is of type Article (I have some other type of potential RootMessages). But I can't seem to find how to add that kind of constraint in a criteria.
For now my code is this:
public virtual ICollection<Comment> GetCommentsByArticle(ISession session)
{
var c = session.CreateCriteria(typeof(Comment))
.Add(Expression.Eq("Author", this))
.AddOrder(Order.Desc("CreationDate"))
.SetMaxResults(20);
var commentList = c.List<Comment>();
return commentList;
}
But of course this returns every single comment of this Author. What I want is every single comment of this Author that have a RootMessage of the Article type.
These are the mappings.
Message:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="FolkeLib"
namespace="Folke.Code.Domain">
<class name="Message" discriminator-value="0">
<id name="Id">
<generator class="native"></generator>
</id>
<discriminator column="MessageType" type="Int32"/>
<timestamp column="ModificationDate" name="ModificationDate"/>
<property name="CreationDate" index="ArticleCreationDate"/>
<many-to-one name="Author"/>
<property name="Text" type="StringClob">
<column name="Text" sql-type="text"/>
</property>
<property name="Locked"/>
<many-to-one name="Locker" not-null="false"/>
<many-to-one name="RootMessage" not-null="false"/>
<many-to-one name="ParentMessage" not-null="false"/>
<property name="Score"/>
<many-to-one name="Site" not-null="true"/>
Article:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="FolkeLib"
namespace="Folke.Code.Domain">
<subclass name="Article" extends="Message" discriminator-value="1">
<property name="Title"/>
<set name="TagSet" lazy="true" table="MessageTag">
<key column="MessageId"/>
<many-to-many class="Tag" column="TagId"/>
</set>
<set name="ImageSet" lazy="true" table="MessageImage">
<key column="MessageId"/>
<many-to-many class="Image" column="ImageId"/>
</set>
<many-to-one name="Forum"/>
</subclass>
</hibernate-mapping>
Comment (class is pretty much empty for now):
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="FolkeLib"
namespace="Folke.Code.Domain">
<subclass name="Comment" extends="Message" discriminator-value="2">
</subclass>
</hibernate-mapping>
Any help appreciated!
This would be easier to answer if you posted your complete mappings, but I believe something along the lines of:
.CreateAlias("RootMessage", "rm")
.Add(Expression.Eq("rm.class",typeof(Article)))
Is what you're looking for.