-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 
Author Message
 Post subject: No row with the given identifier exists
PostPosted: Tue Aug 14, 2007 3:19 am 
Beginner
Beginner

Joined: Tue May 17, 2005 2:48 pm
Posts: 47
Hi,

I have an Employee class. A property of this class is Manager which is also of the Employee type. The Employee is derived from the Contact class. This two classes correspond with two separate tables in the database: Contact and Employee. These tables have separate primary keys: EmployeeId 10 can correspond with ContactId 5 for example.

This looks like a table-per-subclass strategy, but the primary key values are not identical.

When I get all instances of this class (see stack trace), I get an exception 'No row with the given identifier exists'. I guess this could lie in the fact that I didn't map the EmployeeId, but where should I do that?

I made a joined-subclass element in my mapping (see underneath) but I don't have to the possibility to map the EmployeeId. The <id> element is not present in the joined-subclass. I could make a many-to-one relationship so that Contact becomes a property of Employee, but then I would lose the benefits of inheritance and I have to wrap the functionality of the Contact class into the Employee class. I would not like that.

Could anyone help me with this mapping problem?

Greets,
Nils

Hibernate version: 1.2.0

Mapping documents:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="MyProject.Domain" namespace="MyProject.Domain">
<joined-subclass name="Employee" extends="Contact" lazy="false" table="Employee" >
<key column="ContactID" />
<many-to-one name="Manager" column="ManagerID" class="Employee" />
</joined-subclass>
</hibernate-mapping>

Full stack trace of any exception that occurs:

[UnresolvableObjectException: No row with the given identifier exists: 21, of class: MyProject.Domain.Employee]
NHibernate.UnresolvableObjectException.ThrowIfNull(Object o, Object id, Type clazz) +88
NHibernate.Impl.SessionImpl.InternalLoad(Type clazz, Object id, Boolean eager, Boolean isNullable) +137
NHibernate.Type.EntityType.ResolveIdentifier(Object id, ISessionImplementor session) +99
NHibernate.Type.EntityType.ResolveIdentifier(Object id, ISessionImplementor session, Object owner) +112
NHibernate.Impl.SessionImpl.InitializeEntity(Object obj) +410
NHibernate.Loader.Loader.InitializeEntitiesAndCollections(IList hydratedObjects, Object resultSetId, ISessionImplementor session) +355
NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) +905
NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) +85
NHibernate.Loader.Loader.DoList(ISessionImplementor session, QueryParameters queryParameters) +81
NHibernate.Loader.Loader.ListIgnoreQueryCache(ISessionImplementor session, QueryParameters queryParameters) +58
NHibernate.Loader.Loader.List(ISessionImplementor session, QueryParameters queryParameters, ISet querySpaces, IType[] resultTypes) +165
NHibernate.Loader.Criteria.CriteriaLoader.List(ISessionImplementor session) +80
NHibernate.Impl.SessionImpl.Find(CriteriaImpl criteria, IList results) +487
NHibernate.Impl.SessionImpl.Find(CriteriaImpl criteria) +123
NHibernate.Impl.CriteriaImpl.List() +112

Name and version of the database you are using: SQL Server 2005


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 14, 2007 9:55 am 
Hibernate Team
Hibernate Team

Joined: Tue Jun 13, 2006 11:29 pm
Posts: 315
Location: Calgary, Alberta, Canada
Parent class and subclass must have the same primary key. I am not aware of any way to circumvent that. One obvious work-around is to map your Contact and Employee classes separately (without inheritance) and create a many-to-one association from Employee to Contact.

_________________
Karl Chu


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 14, 2007 10:34 am 
Beginner
Beginner

Joined: Tue May 17, 2005 2:48 pm
Posts: 47
I guess you're right, Karl. I played a bit (like a few hours) with the mapping file to see what happens in different situations, but I couldn't make it work.

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="MyProject.Domain" namespace="MyProject.Domain">
<joined-subclass name="Employee" extends="Contact" lazy="false" table="Employee" >
<key column="ContactID" foreign-key="ContactID" />
<many-to-one name="Manager" column="ManagerID" class="Employee" foreign-key="EmployeeID" />
</joined-subclass>
</hibernate-mapping>

This mapping makes sure that the Employee record is correctly coupled with a Contact record. (Employee.ContactId = Contact.ContactId).
But because the key column is now ContactId for the Employee class, the join that is made by NHibernate to get the Manager association is wrongly made by NHibernate (Employee1.ManagerId = Employee2.ContactId). The fact that I provided the many-to-one element with a foreign-key attribute didn't change that (should it?).
And then I haven't gone to the point where I should get new employees in the database. You should be able to map EmployeeId somewhere then and make it clear to NHibernate that this is also an identity field in the database.

For clarity, the tables look like this:
----------------------------------------
Contact
----------------------------------------
ContactId
FirstName
LastName
etc.

----------------------------------------
Employee
----------------------------------------
EmployeeId
ContactId
ManagerId
HireDate
etc.

To make this an inheritance structure, the ContactId field in Employee should be joined with the ContactId field in Contact. Apparently, NHibernate only allows joining two primary keys together and not joining a primary key with a foreign key. Above database design is not very rare in my opinion. So NHibernate forces you to design your database in a specific way in this situation. It could be a reason to not use NHibernate in a project. Because I like using NHibernate, I would like to try solving this issue in the future (when I get the time).

Comments and opinions of possible solutions (of people who are more acquinted with the internals of NHibernate) on this problem are very welcome.

In the mean while, I made a many-to-one association from Employee to Contact, like Karl suggested. But then I ran into another problem when I create the criteria to get the employees ordered by LastName.

ICriteria criteria = NHibernateSession.CreateCriteria(persitentType);
criteria.AddOrder(Order.Asc("Contact.LastName"));

LastName is not a property of Employee anymore, so I have to call Contact.LastName in some way. But above syntax doesn't work with AddOrder. How should I order my collection based on properties of the Contact association?

Greets,
Nils


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 14, 2007 11:51 am 
Expert
Expert

Joined: Fri May 13, 2005 11:13 am
Posts: 292
Location: Rochester, NY
Try
Code:
criteria.CreateAlias( "Contact", "c" ).AddOrder(Order.Asc("c.LastName"));


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.