how to move from poid to hilo in nhibernate - nhibernate

I have been having a lot of trouble with deadlocks. I've received some really useful feedback that suggested this may be a side effect of my use of identity which is a regular id. My application is of reasonable size. 20-30 entities. Making a major change like this is quite a scary proposition. So would be very grateful for some feedback
1) what would i need to do to change to hilo. This application has quite a lot of data. Would i need to do some kind of data migration.
2) is hilo the correct choice, would guid be an easier upgrade.
An example entity mapping. I'm using nhibernate 2
<class name="Post" table="Post">
<id name="Id" type="Int32" column="Id" unsaved-value="0">
<generator class="identity"/>
</id>
<many-to-one name="Company" column="CompanyId" class="EStore.Domain.Model.Company, EStore.Domain" />
<many-to-one name="Retailer" column="RetailerId" class="EStore.Domain.Model.Retailer, EStore.Domain" />
<many-to-one name="Parent" column="ParentId" class="EStore.Domain.Model.Post, EStore.Domain" />
<many-to-one name="PostStatus" column="PostStatusId" class="EStore.Domain.Model.PostStatus, EStore.Domain" />
</class>

highlow needs a source for high (table or sequence) and calculates a lowvalue.
you need a sequence/table which value * maxlowvalue(the value you define in the mapping) is greater than the highest id in your database/table(if you give each table a different highvalue sequence/table)

Related

Polymorfic many-to-one NHibernate Mapping

I'm trying to map the following classes:
PessoaFisica and PessoaJuridica inherits Pessoa.
Cliente has an association with Pessoa, it may be PessoaJuridica or PessoaFisica.
When I save a Cliente object with PessoaFisica, for example, thats ok. But when I try to update and I set the property Pessoa from Cliente to PessoaJuridica and try to update, it updates, but it generates a new row in table TB_PESSOA and the old row, in PessoaFisica is not deleted. It creates a new row to PessoaJuridica, but the old row remains. What's wrong with my mapping XMLs ? Why NHibernate does not delete the old row before insert the new polymorphic object ?
Those are the mapping files I am using
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
namespace="SALClassLib.Masterdata.Model" assembly="SALClassLib">
<class name="Pessoa" table="TB_PESSOA">
<id name="Id">
<column name="ID_PESSOA" not-null="true"/>
<generator class="increment" />
</id>
(other properties...)
<joined-subclass name="PessoaFisica" table="TB_PESSOA_FISICA">
<key column="ID_PESSOA" />
(other properties...)
</joined-subclass>
<joined-subclass name="PessoaJuridica" table="TB_PESSOA_JURIDICA">
<key column="ID_PESSOA" />
(other properties...)
</joined-subclass>
</class>
<class name="Cliente" table="TB_CLIENTE">
<id name="Id">
<column name="ID_CLIENTE" not-null="true"/>
<generator class="increment" />
</id>
<many-to-one name="Pessoa" class="Pessoa" cascade="all" column="ID_PESSOA" not-null="true" unique="true" />
Thank you
NHibernate cascading is nicely explained here: NHibernate Cascades: the different between all, all-delete-orphans and save-update
One of the option, is cascade="all-delete-orphan" which could be seen as what you are asking for.
BUT
Cascading deletion of the orphans is correct only in parent-child scenario (no parent ==> no children) or one-to-one mapping. (i.e not vice versa child-parent)
In your case, you do ask for deletion of the referenced object. But NHibernate (well no-one) can know, if it is not referenced by some other "child".
If you need to delete previous Person assigned, you can always do it in code - but explicitly

NHibernate simple collection of joined-subclass entities

I'm trying to map a set of joined-subclass entities to a parent entity. The SQL being produced by NHibernate seems to be incorrect. Am I missing anything in my mapping? Is there another way I can approach this problem?
<class name="ResultItem" table="result">
<id name="ID">
<generator class="identity" />
</id>
<many-to-one name="Job" column="JobID"/>
<property name="Timestamp"/>
<many-to-one name="User" column="UserID"/>
<joined-subclass name="ResultItemAttachment" table="result_attachment">
<key column="ID"/>
<property name="Comment"/>
</joined-subclass>
</class>
This is the SQL being generated by NHibernate. It seems as if its getting confused between super and sub class members? The only table with JobID is the result table and not result_attachment.
SELECT attachment0_.JobID as JobID1_,
attachment0_.ID as ID1_,
attachment0_.ID as ID26_0_,
attachment0_1_.JobID as JobID26_0_,
attachment0_1_.`Timestamp` as Timestamp26_0_,
attachment0_1_.UserID as UserID26_0_,
attachment0_.`Comment` as Comment33_0_
FROM result_attachment attachment0_
inner join result attachment0_1_ on attachment0_.ID=attachment0_1_.ID
WHERE attachment0_1_.JobID=?;
Thanks in advance
I'm afraid this is currently a bug in NHibernate (in there since 2.1 :|) apperently there is a fix in the current alpha of 3.2
https://nhibernate.jira.com/browse/NH-1747
Possible work around is to manually fetch the bag at runtime. Hardly ideal, other option would be to try and get the alpha version running but running an alpha in a production environment is hardly a great idea.

NHibernate doesn't delete db record when object is set to null?

I have two classes: Family and Address.
A family has a physical address and a mailing address.
The mapping file for Family looks like:
....
<id name="Id" column="Id" type="Int32" unsaved-value="0">
<generator class="native"></generator>
</id>
<many-to-one name="PhysicalAddress" class="Address" column="PhysicalAddressId" cascade="all" unique="true" />
<many-to-one name="MailingAddress" class="Address" column="MailingAddressId" cascade="all" unique="true" />
...
The mapping file for Address looks like:
...
<id name="Id" column="Id" type="Int32" unsaved-value="0">
<generator class="native"></generator>
</id>
<property name="StreetAddress1" column="StreetAddress1" />
<property name="StreetAddress2" column="StreetAddress2"/>
<property name="City" column="City" />
<property name="State" column="State" />
<property name="ZipCode" column="ZipCode" />
...
(Note that Family-PhysicalAddress and Family-MailingAddress are one-to-one relationships.)
What I would like to happen is that when I execute
aFamily.MailingAddress = null;
session.Save(aFamily);
session.Flush();
I expect NHibernate to automatically delete the mailing address record from SQL Server for me.
BUT, that doesn't happen. NHibernate does not delete the address record from SQL Server.
Is there any way I can make it work?
Thank you!
This behaviour isn't supported by NHibernate. Of course the problem is that you probably don't have access to the NHibernate session in your domain logic where the change is made.
One possible -- though admittedly not ideal solution -- is to simply run another process to clean up orphaned entities.
Here is a discussion of this scenario:
http://colinjack.blogspot.com/2008/03/nhibernate-gotchas-orphans-and-one-to.html
And a link to a ticket on the issue:
https://nhibernate.jira.com/browse/NH-1262
Unfortunately NHibernate currently does not support automatic deletions of orhphans for many-to-one (Hibernate v3 in Java does support it). It is only supported on lists (cascade="all-delete-orphan").
What you can try to do is to use component mapping. Maybe it is possible to embed many-to-one into a component.
But I think it would better to explicitly delete the related object.

NHibernate inheritance question

Currently I have the following classes:
class Article with properties id, title and body
class Question : Article with an extra PostedBy property
Then I have a table called Article with the above properties and a table called questions with an ID a foreign key articleID and a PostedBy. Both are in different schemas
I would like to know how are my mappings going to look to represent this relation. Both classes are in different assemblies and i would be very reluctant to put Question logic in Article class/mapping and its assembly.
NHibernate supports three basic inheritance strategies.
table per class hierarchy
table per subclass
table per concrete class
It sounds like you are looking for the table per subclass strategy as you have a table for your Article class and another table for the extra properties on the Question subclass. The mapping might looks something like this:
<class name="Article" table="Article">
<id name="Id" type="Int64" column="ArticleId">
<generator class="native"/>
</id>
<property name="Title" column="Title"/>
<property name="Body" column="Body"/>
...
<joined-subclass name="Question" table="Question">
<key column="ArticleId"/>
<property name="PostedBy" column="PostedBy"/>
...
</joined-subclass>
</class>
However, this doesn't meet your desire to keep the mappings entirely separate. You could have entirely separate mappings, but this might have some side effects as allowing Question to be loaded as a plain Article instead of a Question. With separate mapping the Article class would be straight-forward as expected. The Question class would include a join to access the properties stored in the Article table.
<class name="Article" table="Article">
<id name="Id" type="Int64" column="ArticleId">
<generator class="native"/>
</id>
<property name="Title" column="Title"/>
<property name="Body" column="Body"/>
...
</class>
<class name="Question" table="Question">
<id name="Id" type="Int64" column="QuestionId">
<generator class="native"/>
</id>
<property name="PostedBy" column="PostedBy"/>
...
<join table="Article">
<key column="ArticleId"/>
<property name="Title" column="Title"/>
<property name="Body" column="Body"/>
</join>
</class>

Use two joined subclasses in nhibernate

Ok, new to nhibernate and I am working on a project that has already fully implemented it.
Scenerio: One class (Person) has two joined subclasses (RoleA and RoleB).
What I need is that a given person can actually be both in RoleA and RoleB. How, when given a person that is already created and in RoleA, can I then make them also in RoleB while maintaining the relationships with RoleA?
So, you have something like the following (with Students and Teachers taking the place of RoleA and RoleB):
<class name="Person" table="Persons" >
<id name="Id" column="PersonID">
<generator class="native" />
</id>
<property name="Name" column="Name" not-null="true" />
<joined-subclass name="Student" table="Students">
<key column="PersonID" />
<property name="Grade" column="Grade" not-null="true" />
</joined-subclass>
<joined-subclass name="Teacher" table="Teachers">
<key column="PersonID" />
<property name="ClassName" column="ClassName" not-null="true" />
</joined-subclass>
</class>
If that is the case, your best bet is to use a one-to-one mapping to accomplish the same thing. Here is a good reference: http://nhibernate.info/doc/nh/en/index.html#mapping-declaration-onetoone
This person had a similar problem as you, and ended up going with the one-to-one mapping option:
http://groups.google.com/group/nhusers/browse_thread/thread/1d83e0cd3c2bf58f