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.
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
Wondering if anyone could point me in the right direction..
I currently have the following 3 tables in my sqlserver database
Parameter
ParameterId
ParameterName
ParameterValue
ParameterValueId
ParameterValue
ParameterParameterValue
ParameterId
ParameterValueId
I'm trying to get it where the Parameter domain object will also fetch all the ParameterValue objects as well (I'm guessing Parameter has a one-to-many relationship with ParameterValue, since a parameter can have more than one value) but I'm getting no where - the msot I've achieved is fetching the first value, rather than all :(
If anyone is willing to help or anything I can post some code and/or the mappings I'm using - as always, any help is much appreciated :)
Mappings for Parameter
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
namespace="StockMarketAdvisorDatabaseAccess.Domain"
assembly="StockMarketAdvisorDatabaseAccess">
<class name="Parameter" table="Parameter">
<id name="ParameterId">
<column name="ParameterId" sql-type="int" not-null="true" />
<generator class="identity" />
</id>
<property name="ParameterName" />
<bag name="ParameterValues" table="ParameterParameterValue" cascade="none">
<key column="ParameterValueId" />
<one-to-many class="ParameterValue" />
</bag>
</class>
</hibernate-mapping>
Mappings for ParameterValue
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
namespace="StockMarketAdvisorDatabaseAccess.Domain"
assembly="StockMarketAdvisorDatabaseAccess">
<class name="ParameterValue" table="ParameterValue">
<id name="ParameterValueId">
<column name="ParameterValueId" sql-type="int" not-null="true" />
<generator class="identity" />
</id>
<property name="Value" column="ParameterValue"/>
</class>
</hibernate-mapping>
Thanks again, just started using nHibernate so still trying to figure most it out! :)
Your issue is you are describing one thing (1-many) but your table structure is another (many-many)
If you need many values per parameter then you should simplify your table structure to:
Parameter
-------------
* ParameterId
ParameterName
ParameterValue
--------------------
* ParameterValueId
ParameterId
ParameterValue
Then your mapping can use a 1-many mapping:
<class name="Parameter" table="Parameter">
<id name="ParameterId">
<column name="ParameterId" sql-type="int" not-null="true" />
<generator class="identity" />
</id>
<property name="ParameterName" />
<bag name="ParameterValues" table="ParameterValue" cascade="none">
<key column="ParameterId" />
<one-to-many class="ParameterValue" />
</bag>
</class>
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 trying to map a SQL Server database with nHibernate that is full of tables with varchar primary keys that are generated by external software and I need update/read (no insert) access.
I cannot find a way to get past the following error:
XXXX.Tests.GMCRepository_Fixture.Can_get_existing_GMC_by_parameter'
failed: NHibernate.MappingException :
XXXX.Domain.Mappings.GMC2.hbm.xml(4,6): XML validation error: The element 'class' in namespace 'urn:nhibernate-mapping-2.2' has invalid child element 'property' in namespace 'urn:nhibernate-mapping-2.2'. List of possible elements expected: 'meta, subselect, cache, synchronize, comment, tuplizer, id, composite-id' in namespace 'urn:nhibernate- mapping-2.2'.
Research has suggested this error is relating to there not being a valid primary key (id) defined.
Mapping XML looks like:
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping assembly="XXXX.Domain" namespace="XXXX.Domain" xmlns="urn:nhibernate-mapping-2.2" schema="GM.dbo">
<class name="GMC2" table="C2" lazy="true" >
<property name="PARAMETER">
<column name="PARAMETER" sql-type="varchar" not-null="true" />
</property>
...
<id name="Recid">
<column name="recid" sql-type="varchar" not-null="true" />
</id>
</class>
</hibernate-mapping>
Thanks for your help!
I believe that the convention is to have the ID mapping as the first thing under the class declaration.
Also as part of the Id mapping you need to specify the Generator of the ID. In your case I think you will need the assigned generator added to your ID mapping. Your class mapping will look something like this.
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping assembly="XXXXCRMAPI.Domain" namespace="XXXXCRMAPI.Domain" xmlns="urn:nhibernate-mapping-2.2" schema="GoldMine.dbo">
<class name="GMContact2" table="CONTACT2" lazy="true" >
<id name="Recid">
<generator type="assigned" />
<column name="recid" sql-type="varchar" not-null="true" />
</id>
<property name="Accountno">
<column name="ACCOUNTNO" sql-type="varchar" not-null="true" />
</property>
...
</class>
</hibernate-mapping>
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.