-->
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: Using many-to-one and unique for one to one relationships
PostPosted: Wed Jul 27, 2005 1:02 pm 
Newbie

Joined: Wed Jul 27, 2005 12:30 pm
Posts: 4
I'm having an issue I cannot seem to find a solution for. I am hoping someone here can help.

I put together a very simple application to reproduce the issue outside of my real project. .

I am using Hibernate 2.1.8.

I have a LeftHand class, and a RightHand class.
Each class has a property for the other class.
For example...
rightHand.setLeftHand(leftHand);
leftHand.setRightHand(rightHand);

Both objects use simple native id generator mappings, so nothing special there. The goal I'm trying to achieve is this.

A LeftHand table, with a column for the RightHand id.
A RightHand table with a column for the LeftHand id.
Each object should it's own id primary key (no export from lefthand).
The rightHand property on LeftHand should be nullable, but unique.
RightHand objects must have a LeftHand object to exist.


Here are my mappings...

Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping default-cascade="save-update">
    <class name="LeftHand">

        <id name="id">
            <generator class="native"/>
        </id>

        <many-to-one name="rightHand" class="RightHand" cascade="all" unique="true" />

    </class>
</hibernate-mapping>


RightHand
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping default-cascade="save-update">
    <class name="RightHand">

        <id name="id">
            <generator class="native"/>
        </id>

        <many-to-one name="leftHand" class="LeftHand" unique="true" not-null="true" cascade="none" />

    </class>
</hibernate-mapping>


Now, if I run a little test...
Code:
public static void main(String[] args) throws Exception {

    Configuration conf = new Configuration();
    conf.addClass(LeftHand.class);
    conf.addClass(RightHand.class);

    SessionFactory sf = conf.buildSessionFactory();

    Session session = sf.openSession();

    RightHand rh = new RightHand();
    LeftHand lh = new LeftHand();

    lh.setRightHand(rh);
    rh.setLeftHand(lh);

    session.save(lh);

}


It yacks with the following...
Code:
net.sf.hibernate.PropertyValueException: not-null property references a null or transient value: RightHand.leftHand
   at net.sf.hibernate.impl.SessionImpl.checkNullability(SessionImpl.java:1287)
   at net.sf.hibernate.impl.SessionImpl.doSave(SessionImpl.java:939)
   at net.sf.hibernate.impl.SessionImpl.doSave(SessionImpl.java:868)
   at net.sf.hibernate.impl.SessionImpl.saveWithGeneratedIdentifier(SessionImpl.java:786)
   at net.sf.hibernate.impl.SessionImpl.save(SessionImpl.java:749)
   at net.sf.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:1398)
   at net.sf.hibernate.engine.Cascades$4.cascade(Cascades.java:114)
   at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:436)
   at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:503)
   at net.sf.hibernate.impl.SessionImpl.doSave(SessionImpl.java:901)
   at net.sf.hibernate.impl.SessionImpl.doSave(SessionImpl.java:868)
   at net.sf.hibernate.impl.SessionImpl.saveWithGeneratedIdentifier(SessionImpl.java:786)
   at net.sf.hibernate.impl.SessionImpl.save(SessionImpl.java:749)
   at Main.main(Main.java:32)


I don't understand why saving LeftHand isn't cascading to RightHand. I've been messing with this far too long and appreciate any help here.

Thanks
-Ray


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 28, 2005 10:04 am 
Beginner
Beginner

Joined: Wed Feb 23, 2005 2:23 pm
Posts: 21
Location: Pescara, italy
Hi Ray

Try to change your RightHand mapping:

Code:
<hibernate-mapping default-cascade="save-update">
    <class name="RightHand">

        <id name="id">
            <generator class="native"/>
        </id>

       <one-to-one name="leftHand" class="LeftHand" property-ref="rightHand"/>

    </class>
</hibernate-mapping>


Does that help?

Gruß
Kai


Top
 Profile  
 
 Post subject: Re: Using many-to-one and unique for one to one relationship
PostPosted: Thu Jul 28, 2005 11:10 am 
Expert
Expert

Joined: Mon Feb 14, 2005 12:32 pm
Posts: 609
Location: Atlanta, GA - USA
Just save(rh) instead of lh and remove cascade="none" from the rightHand.leftHand many-to-one mapping.

Code:
<many-to-one name="leftHand" class="LeftHand" unique="true" not-null="true" />

session.save(rh);


Here's why -
You have LH mapped as cascade="all" for RH.
Therefore, when you try to save LH, Hibernate will first cascade all relationships, in this case it will try and save RH first.

However RH contains an LH, which has not yet been saved and therefore it can't properly update the ID value in the RH table so it sets the reference to null before trying to save RH. That causes the null reference exception.

I hope this helps.
Preston


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 18, 2005 6:55 am 
Newbie

Joined: Wed Jul 27, 2005 12:30 pm
Posts: 4
I just wanted to close ths out...

I ended up going with many-to-one from all the rightHand elements to the leftHand. And one-to-one from the leftHand to the rightHand elements. That worked out great.


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.