-->
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.  [ 8 posts ] 
Author Message
 Post subject: Problem in <one-to-one> Mapping
PostPosted: Thu May 04, 2006 8:02 am 
Beginner
Beginner

Joined: Fri Apr 28, 2006 7:48 am
Posts: 20
The following are the tables

usr
user_id (pk)
firstname


usrddr
addr_id (pk) (fk-> refers the usr table column user_id)
street
zipcode

The following are the mapping files for the above tables
<hibernate-mapping>
<class name="Usr" table="Usr">
<id name="userid" type="int" unsaved-value="0" column="user_id">
<generator class="increment"/>
</id>
<property name="firstname" />
<one-to-one name="addrid" class="UsrAddr" cascade="save-update"/>
</class>
</hibernate-mapping>



<hibernate-mapping>
<class name="UsrAddr" table="UsrAddr">
<id name="addrid" column="addr_id">
<generator class="foreign">
<param name="property">user</param>
</generator>
</id>
<property name="street" />
<property name="zipcode" />
<one-to-one name="user" class="Usr" constrained="true" cascade="all" />
</class>
</hibernate-mapping>



I am using the following code to insert the data in both the parent and the child table.

Configuration cfg=new Configuration().configure();
SessionFactory sessionFactory=cfg.buildSessionFactory();
Session session=sessionFactory.openSession();
Transaction tx=null;
tx=session.beginTransaction();
Usr usr=new Usr();
usr.setFirstname("User bb");

UsrAddr add=new UsrAddr();
add.setStreet("Street A");
add.setZipcode("125");

usr.setAddrid(add);
session.save(usr);
tx.commit();
System.out.println("Data inserted successfully");



The above code generates the following exception. However, if I remove the cascade attribute from the Usr.hbm.xml file , the data gets inserted only in the usr table and the address details (child table) does not get inserted in the table. Can any one please give me a solution on this.

org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property: user
at org.hibernate.id.ForeignGenerator.generate(ForeignGenerator.java:44)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:91)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:186)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:175)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:98)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:520)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:513)
at org.hibernate.engine.CascadingAction$1.cascade(CascadingAction.java:134)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:213)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:157)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:108)



Thanks.


Top
 Profile  
 
 Post subject: Re: Problem in <one-to-one> Mapping
PostPosted: Thu May 04, 2006 8:21 am 
Newbie

Joined: Mon Aug 01, 2005 7:33 am
Posts: 18
Location: UK
If user and address really are a 1:1 relationship (are you sure that users may not exist at the same address??) then you would be better off making the relationship a 1:1 from user and 1:n from address and making the relationship have a unique constraint on the address side (or vice versa on the ends of the relationship) - i.e. there can only be one user with that address (even if it is described as a one to many).

I don't know for sure but I have heard it is best to avoid doing a 1:1??

Good luck

falgunipm wrote:
The following are the tables

usr
user_id (pk)
firstname
usrddr
addr_id (pk) (fk-> refers the usr table column user_id)
street
zipcode

The following are the mapping files for the above tables
<hibernate-mapping>
<class name="Usr" table="Usr">
<id name="userid" type="int" unsaved-value="0" column="user_id">
<generator class="increment"/>
</id>
<property name="firstname" />
<one-to-one name="addrid" class="UsrAddr" cascade="save-update"/>
</class>
</hibernate-mapping>



<hibernate-mapping>
<class name="UsrAddr" table="UsrAddr">
<id name="addrid" column="addr_id">
<generator class="foreign">
<param name="property">user</param>
</generator>
</id>
<property name="street" />
<property name="zipcode" />
<one-to-one name="user" class="Usr" constrained="true" cascade="all" />
</class>
</hibernate-mapping>



I am using the following code to insert the data in both the parent and the child table.

Configuration cfg=new Configuration().configure();
SessionFactory sessionFactory=cfg.buildSessionFactory();
Session session=sessionFactory.openSession();
Transaction tx=null;
tx=session.beginTransaction();
Usr usr=new Usr();
usr.setFirstname("User bb");

UsrAddr add=new UsrAddr();
add.setStreet("Street A");
add.setZipcode("125");

usr.setAddrid(add);
session.save(usr);
tx.commit();
System.out.println("Data inserted successfully");



The above code generates the following exception. However, if I remove the cascade attribute from the Usr.hbm.xml file , the data gets inserted only in the usr table and the address details (child table) does not get inserted in the table. Can any one please give me a solution on this.

org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property: user
at org.hibernate.id.ForeignGenerator.generate(ForeignGenerator.java:44)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:91)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:186)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:175)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:98)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:520)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:513)
at org.hibernate.engine.CascadingAction$1.cascade(CascadingAction.java:134)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:213)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:157)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:108)



Thanks.
Quote:


Top
 Profile  
 
 Post subject: Re: Problem in <one-to-one> Mapping
PostPosted: Thu May 04, 2006 8:29 am 
Beginner
Beginner

Joined: Fri Apr 28, 2006 7:48 am
Posts: 20
Yes, I am very sure that users will not have the same address as that is the requirement. I thought of the suggestion you have given, of using the unique constraint , but for that I will have to change the table structures which I am not supposed to.

Please give me anyother solution incase if you can :-)

Thanks


shaunybee wrote:
If user and address really are a 1:1 relationship (are you sure that users may not exist at the same address??) then you would be better off making the relationship a 1:1 from user and 1:n from address and making the relationship have a unique constraint on the address side (or vice versa on the ends of the relationship) - i.e. there can only be one user with that address (even if it is described as a one to many).

I don't know for sure but I have heard it is best to avoid doing a 1:1??

Good luck

falgunipm wrote:
The following are the tables

usr
user_id (pk)
firstname
usrddr
addr_id (pk) (fk-> refers the usr table column user_id)
street
zipcode

The following are the mapping files for the above tables
<hibernate-mapping>
<class name="Usr" table="Usr">
<id name="userid" type="int" unsaved-value="0" column="user_id">
<generator class="increment"/>
</id>
<property name="firstname" />
<one-to-one name="addrid" class="UsrAddr" cascade="save-update"/>
</class>
</hibernate-mapping>



<hibernate-mapping>
<class name="UsrAddr" table="UsrAddr">
<id name="addrid" column="addr_id">
<generator class="foreign">
<param name="property">user</param>
</generator>
</id>
<property name="street" />
<property name="zipcode" />
<one-to-one name="user" class="Usr" constrained="true" cascade="all" />
</class>
</hibernate-mapping>



I am using the following code to insert the data in both the parent and the child table.

Configuration cfg=new Configuration().configure();
SessionFactory sessionFactory=cfg.buildSessionFactory();
Session session=sessionFactory.openSession();
Transaction tx=null;
tx=session.beginTransaction();
Usr usr=new Usr();
usr.setFirstname("User bb");

UsrAddr add=new UsrAddr();
add.setStreet("Street A");
add.setZipcode("125");

usr.setAddrid(add);
session.save(usr);
tx.commit();
System.out.println("Data inserted successfully");



The above code generates the following exception. However, if I remove the cascade attribute from the Usr.hbm.xml file , the data gets inserted only in the usr table and the address details (child table) does not get inserted in the table. Can any one please give me a solution on this.

org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property: user
at org.hibernate.id.ForeignGenerator.generate(ForeignGenerator.java:44)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:91)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:186)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:175)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:98)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:520)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:513)
at org.hibernate.engine.CascadingAction$1.cascade(CascadingAction.java:134)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:213)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:157)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:108)



Thanks.
Quote:


Top
 Profile  
 
 Post subject: Re: Problem in <one-to-one> Mapping
PostPosted: Thu May 04, 2006 8:45 am 
Newbie

Joined: Mon Aug 01, 2005 7:33 am
Posts: 18
Location: UK
No need to change the table structure only the mapping files:

e.g.

in user:
<one-to-one name="user_addrss" class="address"
property-ref="addr" cascade="save-update, delete" />

in address:
<many-to-one name="user" column="user_id" unique="true"
class="user" cascade="none"/>


or a variation on that. the database doesn't need to know about such changes as the rules are defined within hibernate then and not the database.


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 04, 2006 8:52 am 
Expert
Expert

Joined: Tue Apr 25, 2006 12:04 pm
Posts: 260
This is from reference documentation, section 5.1.11. one-to-one; and may help you.

Quote:
Primary key associations don't need an extra table column; if two rows are related by the association then the two table rows share the same primary key value. So if you want two objects to be related by a primary key association, you must make sure that they are assigned the same identifier value!

For a primary key association, add the following mappings to Employee and Person, respectively.


Code:
<one-to-one name="person" class="Person"/>
<one-to-one name="employee" class="Employee" constrained="true"/>


Quote:
Now we must ensure that the primary keys of related rows in the PERSON and EMPLOYEE tables are equal. We use a special Hibernate identifier generation strategy called foreign:


Code:
<class name="person" table="PERSON">
    <id name="id" column="PERSON_ID">
        <generator class="foreign">
            <param name="property">employee</param>
        </generator>
    </id>
    ...
    <one-to-one name="employee"
        class="Employee"
        constrained="true"/>
</class>


Quote:
A newly saved instance of Person is then assigned the same primary key value as the Employee instance refered with the employee property of that Person.


Top
 Profile  
 
 Post subject:
PostPosted: Fri May 05, 2006 1:23 am 
Beginner
Beginner

Joined: Fri Apr 28, 2006 7:48 am
Posts: 20
Hi bkmr_77,
If you look at the mapping files that I have written,they are exactly the way you have mentioned. Also, as I have written earlier if the cascade attribute is removed, the parent details will get inserted but the child details are not getting inserted. With the cascade attribute it throws an exception as I have mentioned earlier.
Please tell me incase if i am missing out on anything.

Thanks



bkmr_77 wrote:
This is from reference documentation, section 5.1.11. one-to-one; and may help you.

Quote:
Primary key associations don't need an extra table column; if two rows are related by the association then the two table rows share the same primary key value. So if you want two objects to be related by a primary key association, you must make sure that they are assigned the same identifier value!

For a primary key association, add the following mappings to Employee and Person, respectively.


Code:
<one-to-one name="person" class="Person"/>
<one-to-one name="employee" class="Employee" constrained="true"/>


Quote:
Now we must ensure that the primary keys of related rows in the PERSON and EMPLOYEE tables are equal. We use a special Hibernate identifier generation strategy called foreign:


Code:
<class name="person" table="PERSON">
    <id name="id" column="PERSON_ID">
        <generator class="foreign">
            <param name="property">employee</param>
        </generator>
    </id>
    ...
    <one-to-one name="employee"
        class="Employee"
        constrained="true"/>
</class>


Quote:
A newly saved instance of Person is then assigned the same primary key value as the Employee instance refered with the employee property of that Person.


Top
 Profile  
 
 Post subject:
PostPosted: Fri May 05, 2006 3:33 am 
Beginner
Beginner

Joined: Fri Apr 28, 2006 7:48 am
Posts: 20
Got the solution,

In my java code
I had just written
User.setAddress(addr);

I also need to write (Which I thought was not necessary as address was the child of User. But since i guess it is one-one relationship we have to write the below statement).

Address.setUser(usr);




Thanks everyone for the inputs.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 02, 2006 10:01 am 
Beginner
Beginner

Joined: Thu Apr 20, 2006 11:51 am
Posts: 44
Yes ok but what about 3 association 1----to-----1
I mean if I want that User have 2 other association instead only this with address what I have to do?
Is it possible that User have 2 other associations that have the same PK of User?
(User) 1------->1 (Address)
(User) 1------->1 (other1)
(User) 1------->1 (other2)
how can I realize this with mapping xml files?
thanks


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