-->
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.  [ 7 posts ] 
Author Message
 Post subject: How to model zero-to-one relationship?
PostPosted: Wed May 12, 2004 3:00 pm 
Newbie

Joined: Tue May 11, 2004 5:55 pm
Posts: 2
Hi,

I have two classes Foo and Bar. Foo may have 0 or one Bar objects. One Bar object can only belong to one Foo object.

Should we use one-to-one association to model this? I tried this using the following:

On Foo class
<one-to-one name="bar"
class="Bar">
</one-to-one>


On Bar class

<one-to-one name="foo" class="Foo" constrained="true"/>

With this mapping, in the database table of Foo, I don't have bar column. Is this expected? When I save foo and bar by doing :

session.save(bar);
session.save(foo);
I get error
Hibernate error not-null property references a null or transient value: bar:foo.

Can someone give me a hint?

Thanks.

-Jing


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 12, 2004 3:06 pm 
Regular
Regular

Joined: Wed May 05, 2004 3:41 pm
Posts: 118
Location: New Jersey,USA
try using the outer-join="true". This would force Hibernate to do a outerjoin wherein if Foo does not have a Bar it would still return Foo by very nature of Outerjoins.

Hope that helps.

-anand


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 12, 2004 3:25 pm 
Regular
Regular

Joined: Wed May 05, 2004 3:41 pm
Posts: 118
Location: New Jersey,USA
on second thoughts, try this in the mapping:
Code:
<one-to-one name="foo" class="Foo" constrained="false"/>


constrained property would make hibernate think it's a foreign key constraint and expect that Foo is not-null.

-Anand


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 12, 2004 3:28 pm 
Regular
Regular

Joined: Wed May 05, 2004 3:41 pm
Posts: 118
Location: New Jersey,USA
Another more cleaner implementation would be to use a bi-directional <many-to-one> relationship. The documentation has a similar example (Page 37 in the PDF), Employer-Person with a bi-directional relationship.

-Anand


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 12, 2004 4:22 pm 
Newbie

Joined: Tue May 04, 2004 6:31 pm
Posts: 11
I am having a problem with one-to-one relationships in the mapping files and tried to figure it out (i read through the documentation and everything, but I still can't get it).

I am playing with my own bank example. I have User objects and Account objects. Here are my relationships...
  1. A User can have many Accounts, but an Account can only belong to one user (many-to-one).
  2. A User may have a "preferred" account, but it is not required (this is one-to-one cardinality, but one-to-zero participation).

In my User object I have a reference to the preferred account object (with the appropriate getters and setters). Here is what my User.hbm.xml looks like...

Code:
<hibernate-mapping>

*snip*

<!-- List of accounts... this works  -->
<list name="accounts" table="ACCOUNTS" cascade="all">
         <key foreign-key="account_id" column="user_id"/>
         <index column="acct_index"/>
         <one-to-many class="edu.byu.cid.ssp.bank.Account"/>
</list>

<!-- This doesn't work, mainAccount is the preferred account-->
<one-to-one name="mainAccount" class="edu.byu.cid.ssp.bank.Account"
          constrained="false"/>

*snip*

</hibernate-mapping>


Should the <one-to-one> tag be in the Account.hbm.xml? How should I set up the one-to-one tag?

Thanks!
--
Nathan


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 12, 2004 4:23 pm 
Newbie

Joined: Tue May 11, 2004 5:55 pm
Posts: 2
Thanks for your quick reply.

I put the outer-join thing in, but I encountered some other problems. Basically, hibernate document suggests that one-to-one have two varieties to link two classes together: use the same primary key and use foreign key. But I cannot use primary key approach to link two class, as it needs to use "foreign" id generator strategy in Foo class. In our case, we have assigned id in Foo class.

So here is what I have:

In Foo class:

<id name="ID" column="fooID" type="long" unsaved-value="null">
<generator class="assigned"/>
</id>

<one-to-one name="bar" class="Bar" outer-join="true"/>


in Bar class:

<id name="bID" column="bID" type="long" unsaved-value="null">
<generator class="native"/>
</id>
<many-to-one name="fooID" class="Foo" column="fooID" unique="true"/>



When I save my Bar object, I get error:
Hibernate error No persister for: java.lang.Long


In my Bar class, bID and fooID are the only two attributes of type Long. Other attributes are type of String.
I have getter and setter for both bID and fooID class.

Thanks.
-Jing


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 12, 2004 6:17 pm 
Regular
Regular

Joined: Wed May 05, 2004 3:41 pm
Posts: 118
Location: New Jersey,USA
Here's the mapping I used:

Code:

<hibernate-mapping>
<class name="Foo">
  <id name="id" column="seq_foo_id">
   <generator class="sequence">
      <param name="sequence">seq_enc_id</param>
   </generator>
  </id>
  <property name="name"/>
  <one-to-one class="Bar" name="bar" outer-join="true" cascade="all"/>
</class>
<class name="Bar">
  <id name="id" column="seq_bar_id">
   <generator class="sequence">
      <param name="sequence">seq_enc_id</param>
   </generator>
  </id>
  <property name="name"/>
</class>
</hibernate-mapping>



so when you load Foo using the following code:

Code:

Foo myfoo = (Foo)session.load(Foo.class,new Long(172));



and set the "show.sql" property of hibernate to "true". YOu'll see the following in your log:

Code:
select
foo0_.seq_foo_id as seq_foo_id1_,
foo0_.name as name1_,
bar1_.seq_bar_id as seq_bar_id0_,
bar1_.name as name0_
from Foo foo0_, Bar bar1_
where foo0_.seq_foo_id=?
and foo0_.seq_foo_id=bar1_.seq_bar_id(+)


If you set the "outer-join" to false, you'll see the log printing 2 select statements 1 for each table.

To save "Foo" with no Bars, you'll have code like this:
Code:
Foo myfoo = new Foo();
myfoo.setName("Anand1");
//this would insert 1 row into Foo table.
session.save(myfoo);


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 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.