-->
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.  [ 9 posts ] 
Author Message
 Post subject: No row with the given identifier exists
PostPosted: Fri Dec 19, 2003 12:03 pm 
Newbie

Joined: Wed Dec 17, 2003 10:57 am
Posts: 7
I am trying to build a zero-to-one or zero-to-many mapping. However, I have not been able to find any information on this in the documentation, forums, or the web in general.

An example of the relationship I am trying to set up would be a Person record that may or may not have an associated Address record. (I'm working with legacy data, so normalizing to remove the 1-to-1 relationship isn't easy.)

My mappings look like the following:

Person
[code]
<hibernate-mapping schema="KELIB">
<class name="com.test.data.Person" table="Person">
<id name="id" column="ID" type="string">
<generator class="assigned" />
</id>
<property name="name" column="NAME" />
<property name="dob" column="DOB" />
<many-to-one name="address" class="com.test.data.Address" column="id" not-null="true" />
</class>
</hibernate-mapping>
[\code]

Address mapping
[code]
<hibernate-mapping schema="KELIB">
<class name="com.test.data.Address" table="ADDRESS">
<id name="id" column="ID" type="string">
<generator class="assigned" />
</id>
<property name="street" column="STREET" />
<property name="city" column="CITY" />
<property name="state" column="STATE" />
<property name="zip" column="ZIP" />
</class>
</hibernate-mapping>
[/code]

When I run a test that tries to load either a full set of Persons (through session.iterate) or a single Person that does not have an associated Address record, I get the following exception:

UnresolvableObjectException
[code]
net.sf.hibernate.UnresolvableObjectException: No row with the given identifier exists: 100005728, of class: com.test.data.Address
at net.sf.hibernate.UnresolvableObjectException.throwIfNull(UnresolvableObjectException.java:38)
at net.sf.hibernate.impl.SessionImpl.internalLoad(SessionImpl.java:1881)
at net.sf.hibernate.type.ManyToOneType.resolveIdentifier(ManyToOneType.java:68)
at net.sf.hibernate.type.EntityType.resolveIdentifier(EntityType.java:215)
at net.sf.hibernate.impl.SessionImpl.initializeEntity(SessionImpl.java:2132)
at net.sf.hibernate.loader.Loader.doQuery(Loader.java:239)
at net.sf.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:132)
at net.sf.hibernate.loader.Loader.doList(Loader.java:949)
at net.sf.hibernate.loader.Loader.list(Loader.java:940)
at net.sf.hibernate.hql.QueryTranslator.list(QueryTranslator.java:833)
at net.sf.hibernate.impl.SessionImpl.find(SessionImpl.java:1475)
at net.sf.hibernate.impl.QueryImpl.list(QueryImpl.java:39)
at com.test.test.data.SpecialDataTests.testAdmindLoadsNullForMissingPerson(SpecialDataTests.java:64)
at java.lang.reflect.Method.invoke(Native Method)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:392)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:276)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:167)
[/code]

This UnresolvableObjectException exception is understandable, because that is what is happening. What I can't figure out is how to tell Hibernate that it is OK for a Person to not have an Address.

A few other notes:

- I'm using Hibernate 2.1.1 against a DB2 database.

- I also tried this with a one-to-one mapping, with the same results.

- Catching the exception is not helpful, because it is halting the entire session.iterate process. I don't mind handling the exception, but I do need to continue loading the Person records, including the one with the missing Address.

- I have a workaround of loading each Person and then each Address manually and adding the Address to the Person object, but I would prefer to let Hibernate handle the relationship.

- I have seen mention of using an Interceptor or UserType to solve similar problems, but I can't find documentation on these either.


Top
 Profile  
 
 Post subject: Re: No row with the given identifier exists
PostPosted: Fri Dec 19, 2003 1:47 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
Code:
<many-to-one name="address" class="com.test.data.Address" column="id" not-null="true" />


column="id" is wrong, id should refer to the PK of Adress Table, not Person. Hibernate try to load an address with a person PK (as you requested).
There should be a FK column from person to address.

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 19, 2003 1:49 pm 
Expert
Expert

Joined: Tue Sep 16, 2003 4:06 pm
Posts: 318
Location: St. Petersburg, Russia
Look, you specified column="id" in your <many-to-one> mapping. But "id" column is already used for Person id! You must place the name of the column which contains Address, not Person Id.


Top
 Profile  
 
 Post subject: Re: No row with the given identifier exists
PostPosted: Fri Dec 19, 2003 2:23 pm 
Newbie

Joined: Wed Dec 17, 2003 10:57 am
Posts: 7
Thanks, but ...

"id" is the PK of Address in the example above.

I tried giving the Address PK a different name ("AID") and changing the <many-to-one> tag, but then I get the error below, which seems to indicate that putting the PK of Address in the <many-to-one> tag in Person will not work.

Note that Hibernate does load Person objects correctly as long as they have an associated Address. I am trying to figure out how to let Hibernate know that a missing Address is OK and I don't want an UnresolvableObjectException.

[b]Exception given when Address PK is in Person <many-to-one> tag[\b]
Code:
net.sf.hibernate.JDBCException: Could not execute query
    at net.sf.hibernate.impl.SessionImpl.find(SessionImpl.java:1478)
    at net.sf.hibernate.impl.QueryImpl.list(QueryImpl.java:39)
    at com.test.test.data.SpecialDataTests.testAdmindLoadsNullForMissingAddress(SpecialDataTests.java:64)
    at java.lang.reflect.Method.invoke(Native Method)
    at junit.framework.TestCase.runTest(TestCase.java:154)
    at junit.framework.TestCase.runBare(TestCase.java:127)
    at junit.framework.TestResult$1.protect(TestResult.java:106)
    at junit.framework.TestResult.runProtected(TestResult.java:124)
    at junit.framework.TestResult.run(TestResult.java:109)
    at junit.framework.TestCase.run(TestCase.java:118)
    at junit.framework.TestSuite.runTest(TestSuite.java:208)
    at junit.framework.TestSuite.run(TestSuite.java:203)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:392)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:276)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:167)
Caused by: java.sql.SQLException: [SQL0205] Column AID not in table PERSON in KELIB.
    at com.ibm.as400.access.JDError.throwSQLException(JDError.java:533)
    at com.ibm.as400.access.JDError.throwSQLException(JDError.java:504)
    at com.ibm.as400.access.AS400JDBCStatement.commonPrepare(AS400JDBCStatement.java:1302)
    at com.ibm.as400.access.AS400JDBCPreparedStatement.<init>(AS400JDBCPreparedStatement.java:182)
    at com.ibm.as400.access.AS400JDBCConnection.prepareStatement(AS400JDBCConnection.java:1805)
    at com.ibm.as400.access.AS400JDBCConnection.prepareStatement(AS400JDBCConnection.java:1628)
    at net.sf.hibernate.impl.BatcherImpl.getPreparedStatement(BatcherImpl.java:228)
    at net.sf.hibernate.impl.BatcherImpl.prepareQueryStatement(BatcherImpl.java:61)
    at net.sf.hibernate.loader.Loader.prepareQueryStatement(Loader.java:703)
    at net.sf.hibernate.loader.Loader.doQuery(Loader.java:184)
    at net.sf.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:132)
    at net.sf.hibernate.loader.Loader.doList(Loader.java:949)
    at net.sf.hibernate.loader.Loader.list(Loader.java:940)
    at net.sf.hibernate.hql.QueryTranslator.list(QueryTranslator.java:833)
    at net.sf.hibernate.impl.SessionImpl.find(SessionImpl.java:1475)
    ... 14 more


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 19, 2003 2:34 pm 
Expert
Expert

Joined: Tue Sep 16, 2003 4:06 pm
Posts: 318
Location: St. Petersburg, Russia
1. column="" must not to the PK of ADDRESS table, but to name of the column in PERSON table which is used to hold address id. Do you have such a column or you are expecting addressId==personId?

2. not-null must be "false" if you need to allow Person without an Address. And person without an address is a record from PERSON tabel with ADDRESS_ID set to NULL.


Top
 Profile  
 
 Post subject: Re: No row with the given identifier exists
PostPosted: Fri Dec 19, 2003 3:07 pm 
Newbie

Joined: Wed Dec 17, 2003 10:57 am
Posts: 7
I am expecting addressId==personId.

I switched not-null to false - which is what my running code looks like - I don't know which gremlins changed my sample! :)

I also changed to the column name "ID" instead of the mapping name "id" this caused a MappingException that was solved by adding insert="false" update="false" to the <many-to-one>.

Now the same error occurs - throwing UnresolveableObjectException for a Person without an Address.

I think the second part of your #2 sheds light on the issue. Since the PK of Person is also the linked to Address, and by definition is populated, Hibernate assumes the relationship is not null and tries to load the Address.

Maybe I need to figure out a way to configure the mapping from the other direction. In my data, any Address will have a Person, but not all Persons have an Address. The hard part is that I need to be able to load all Persons with and without Addresses, so I can't just use Address as the master.

Thanks for your help!


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 19, 2003 3:56 pm 
Expert
Expert

Joined: Tue Sep 16, 2003 4:06 pm
Posts: 318
Location: St. Petersburg, Russia
Quote:
I am expecting addressId==personId.
...
I also changed to the column name "ID" instead of the mapping name "id" this caused a MappingException that was solved by adding insert="false" update="false" to the <many-to-one>.


You are cheatin here. You clearly have <one-to-one> relationship


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 19, 2003 3:59 pm 
Expert
Expert

Joined: Tue Sep 16, 2003 4:06 pm
Posts: 318
Location: St. Petersburg, Russia
Er.. I mean you should consider implementing your relationship using <one-to-one> instead <many-to-one>


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 19, 2003 4:30 pm 
Newbie

Joined: Wed Dec 17, 2003 10:57 am
Posts: 7
Guilty as charged!

I did mention in the original post that I had used <one-to-one> previously with the same effect.

However, I just changed the code back to <one-to-one> and it works.

Argh! I hate programming by accident, as Dave Thomas calls it.

My best guess, for those who follow, is that I previously had a composite-id on Person that I switched to a regular id during this process.

Thanks dimas for your help. I have at least learned more about how the columns are mapped in these relationships!


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 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:
cron
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.