-->
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.  [ 6 posts ] 
Author Message
 Post subject: one-to-one with foreign key on child table.
PostPosted: Mon Aug 20, 2007 1:06 pm 
Beginner
Beginner

Joined: Thu Mar 01, 2007 9:40 am
Posts: 23
Location: UK
Hi,

I'm trying to create a relationship as below:
Code:
USER:
  ID VARCHAR2(32) PRIMARY KEY
 
 
ADDRESS:
  ID VARCHAR2(32) PRIMARY KEY
  USER_ID VARCHAR2(32) FOREIGN KEY REFERENCES USER(ID)


User has a one-to-one relation with Address, and the foreign key is specified at the address table.

With this, I have the following configurations:

Hibernate version: 2.1.8

Mapping documents:
Code:
<class name="User" table="USER">
    <id name="id"  column="ID">
      <generator class="uuid.hex" />
    </id>
    <one-to-one name="" class="Address" cascade="all" /> 
</class>

<class name="Address" table="USER">
    <id name="id"  column="ID">
      <generator class="uuid.hex" />
    </id>
    <many-to-one name="user" class="User" column="USER_ID" not-null="true" /> 
</class>



Code between sessionFactory.openSession() and session.close():
Code:
doSaveAndRetrieve() {
  HibernateSession session = HibernateUtil.getSession();
  User user = new User();
 
  HibernateUtil.beginTransaction();
  session.save(user);
  HibernateUtil.commitTransaction();
 
  HibernateUtil.closeSession();
 
  session = HibernateUtil.getSession();
  Criteria criteria = session.createCriteria(User.class);
  criteria.add(Expression.eq("id", user.getId()));
  List results = criteria.list();

  Iterator it = results.iterator();
  while (it.hasNext()) {
    user = (User) it.next();
    assertNotNull(user.getAddress());
  } 
}



Name and version of the database you are using: Oracle 8i

The persisting of the Address object is working perfectly fine with this configuration. However, the retrieval of the Address object is not working correctly. The assertNotNull() in above code fails, as Hibernate is unable to get the linked Address object for a User. The query generated by Hibernate is as below:

The generated SQL (show_sql=true):
Code:
select this.ID as ID2_, address1_.ID as ID0_, address1_.USER_ID as USER1_0_ from USER this, ADDRESS address1_ where this.ID=? and this.ID=address1_.ID(+)



This is an incorrect query. The WHERE clause should have been:
where this.ID=? and this.ID=address1_.USER_ID(+)

How can I specify the mapping for such a relationship? There seems to be a restriction on Hibernate that when specifying one-to-one, the foreign key should be specified on the parent table itself to the child table. Is this a limitation of Hibernate?

Thanks,

_________________
Sam.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 20, 2007 3:11 pm 
Newbie

Joined: Tue Aug 15, 2006 3:43 pm
Posts: 5
I think you need to add inverse = true on your Address mapping. See here.


Top
 Profile  
 
 Post subject: Re: one-to-one with foreign key on child table.
PostPosted: Thu Dec 18, 2008 11:23 pm 
Regular
Regular

Joined: Tue Feb 19, 2008 6:05 pm
Posts: 82
I have the same issue, how do we fix this?

Jikes2005 wrote:
Hi,

I'm trying to create a relationship as below:
Code:
USER:
  ID VARCHAR2(32) PRIMARY KEY
 
 
ADDRESS:
  ID VARCHAR2(32) PRIMARY KEY
  USER_ID VARCHAR2(32) FOREIGN KEY REFERENCES USER(ID)


User has a one-to-one relation with Address, and the foreign key is specified at the address table.

With this, I have the following configurations:

Hibernate version: 2.1.8

Mapping documents:
Code:
<class name="User" table="USER">
    <id name="id"  column="ID">
      <generator class="uuid.hex" />
    </id>
    <one-to-one name="" class="Address" cascade="all" /> 
</class>

<class name="Address" table="USER">
    <id name="id"  column="ID">
      <generator class="uuid.hex" />
    </id>
    <many-to-one name="user" class="User" column="USER_ID" not-null="true" /> 
</class>



Code between sessionFactory.openSession() and session.close():
Code:
doSaveAndRetrieve() {
  HibernateSession session = HibernateUtil.getSession();
  User user = new User();
 
  HibernateUtil.beginTransaction();
  session.save(user);
  HibernateUtil.commitTransaction();
 
  HibernateUtil.closeSession();
 
  session = HibernateUtil.getSession();
  Criteria criteria = session.createCriteria(User.class);
  criteria.add(Expression.eq("id", user.getId()));
  List results = criteria.list();

  Iterator it = results.iterator();
  while (it.hasNext()) {
    user = (User) it.next();
    assertNotNull(user.getAddress());
  } 
}



Name and version of the database you are using: Oracle 8i

The persisting of the Address object is working perfectly fine with this configuration. However, the retrieval of the Address object is not working correctly. The assertNotNull() in above code fails, as Hibernate is unable to get the linked Address object for a User. The query generated by Hibernate is as below:

The generated SQL (show_sql=true):
Code:
select this.ID as ID2_, address1_.ID as ID0_, address1_.USER_ID as USER1_0_ from USER this, ADDRESS address1_ where this.ID=? and this.ID=address1_.ID(+)



This is an incorrect query. The WHERE clause should have been:
where this.ID=? and this.ID=address1_.USER_ID(+)

How can I specify the mapping for such a relationship? There seems to be a restriction on Hibernate that when specifying one-to-one, the foreign key should be specified on the parent table itself to the child table. Is this a limitation of Hibernate?

Thanks,


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 25, 2009 12:21 am 
Newbie

Joined: Wed Feb 25, 2009 12:13 am
Posts: 1
it work for me:

Code:
<class name="User" table="USER">
    <id name="id"  column="ID">
      <generator class="uuid.hex" />
    </id>
    <one-to-one name="address" class="Address" cascade="all" property-ref="user" />
</class>

<class name="Address" table="USER">
    <id name="id"  column="ID">
      <generator class="uuid.hex" />
    </id>
    <many-to-one name="user" class="User" column="USER_ID" not-null="true" />
</class>


Top
 Profile  
 
 Post subject: Re:
PostPosted: Thu May 28, 2009 11:14 am 
Regular
Regular

Joined: Tue Feb 19, 2008 6:05 pm
Posts: 82
sandraluz wrote:
it work for me:

Code:
<class name="User" table="USER">
    <id name="userId"  column="ID">
      <generator class="uuid.hex" />
    </id>
    <one-to-one name="address" class="Address" cascade="all" property-ref="user" />
</class>

<class name="Address" table="USER">
    <id name="addressId"  column="ID">
      <generator class="uuid.hex" />
    </id>
    <many-to-one name="user" class="User" column="USER_ID" not-null="true" />
</class>



Woow, that property-ref really did the trick, to join the primary key (userId) with the property field (user) rather than the primary key of the Address(addressId), wonder why the name is so confusing, 'property-ref'?

Also in the hibernate documentation:
constrained (optional) specifies that a foreign key constraint on the
primary key of the mapped table references the table of the associated
class. This option affects the order in which save() and delete() are
cascaded, and determines whether the association may be proxied (it is
also used by the schema export tool).

So in my case, constrained='true' would specify that a foreign key constraint on the primary key (userId?) of the mapped table (User?) references the table of the associated class (Address?).

What exactly is constrained doing and what is its use?


Top
 Profile  
 
 Post subject: one-to-one relationship with two columns
PostPosted: Thu May 28, 2009 11:23 am 
Regular
Regular

Joined: Tue Feb 19, 2008 6:05 pm
Posts: 82
All I was trying to achieve was to perform a left join from user to address and this is so complicated. Wonder when left join like ANSI sql will be introduced in HQL.

Also, what would I have to do in the case where I have many addresses for a given user however there is yet another field in user, for example, countryId, which when joined with Address countryId will give me a unique address and is one-to-one?

Essentially how do I map a one-to-one relationship when I have two columns to link from user to address tables?


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