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: Saving a parent-child relationship
PostPosted: Mon May 09, 2005 11:20 am 
Newbie

Joined: Mon May 09, 2005 7:48 am
Posts: 5
I am using Hibernate 3, and I have a very basic relationship of a Employee and Address class:

Code:
<hibernate-mapping>
    <class
        name="org.appfuse.model.Employee"
        table="EMPLOYEES">

        <id
            name="empnumber"
            column="EMPNUMBER"
            type="java.lang.Long">
            <generator class="increment"/>
        </id>

        <property
            name="surname"
            type="java.lang.String"
            update="true"
            insert="true"
            column="SURNAME"
            length="50"
            not-null="true"
        />

        <property
            name="forenames"
            type="java.lang.String"
            update="true"
            insert="true"
            column="FORENAMES"
            length="100"
            not-null="true"
        />

        <one-to-one
            name="employeesAddress"
            class="org.appfuse.model.EmployeesAddress"
            cascade="all"
            outer-join="auto"
            constrained="false"
        />
</class>
</hibernate-mapping>

<hibernate-mapping>
    <class
        name="org.appfuse.model.EmployeesAddress"
        table="EMPLOYEES_ADDRESS">

        <id
            name="employeesNumber"
            column="EMPLOYEES_NUMBER"
            type="java.lang.Long">
            <generator class="assigned"/>
        </id>

        <property
            name="address1"
            type="java.lang.String"
            update="true"
            insert="true"
            column="ADDRESS_1"
            length="50"
            not-null="true"
        />

        <property
            name="address2"
            type="java.lang.String"
            update="true"
            insert="true"
            column="ADDRESS_2"
            length="50"
        />

        <property
            name="postcode"
            type="java.lang.String"
            update="true"
            insert="true"
            column="POSTCODE"
            length="20"
        />

        </class>
</hibernate-mapping>


I have a situation where I have to add the Employee and their Address in one save i.e.

Code:
Employee employee = new Employee();
employee.setForenames(applicant.getForenames());
employee.setSurname(applicant.getSurname());

ApplicantAddress applicantAddress = applicant.getApplicantAddress();

EmployeesAddress employeesAddress = new EmployeesAddress();
employeesAddress.setAddress1(applicantAddress.getAddress1());
employeesAddress.setAddress2(applicantAddress.getAddress2());
employeesAddress.setPostcode(applicantAddress.getPostcode());

employee.setEmployeesAddress(employeesAddress);

getHibernateTemplate().saveOrUpdate(employee);


However, I receive the error:

Quote:
ids for this class must be manually assigned before calling save(): org.appfuse.model.EmployeesAddress; nested exception is org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): org.appfuse.model.EmployeesAddress


This as I undertstand is because Hibernate does not save the Employee, retrieve it's new id and populate that into EmployeeAddress and consequently save that.

What is the best solution for this? I cannot seem to find a way retreiving the id of Employee after insert, nor to find a way of Hibernate to automatically cascade the update whilst managing the id's.

Any help would be greatly appreciated.

Regards,
Peter


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 09, 2005 11:26 am 
Senior
Senior

Joined: Tue Feb 08, 2005 5:26 pm
Posts: 157
Location: Montréal, Québec - Canada
You problem is in the following mapping:

<id
name="employeesNumber"
column="EMPLOYEES_NUMBER"
type="java.lang.Long">
<generator class="assigned"/>
</id>

The generator class is set to -assigned- which means that hibernate will require you to create the primary key value for your entity.

Change this value for something else (increment, hilo etc), or set the id on the entity before persisting it.

Have a good day :)

_________________
Vincent Giguère
J2EE Developer


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 09, 2005 11:30 am 
Newbie

Joined: Mon May 09, 2005 7:48 am
Posts: 5
The the primary key of EMPLOYEES_ADDRESS is employeeReference, which a foreign key of the EMPLOYEES table.

Therefore, I need the EmployeesAddress, employeeReference to be populated with the id of it's parent - Employee, prior to insertion.

Any way Hibernate can do this?


vgiguere wrote:
You problem is in the following mapping:

<id
name="employeesNumber"
column="EMPLOYEES_NUMBER"
type="java.lang.Long">
<generator class="assigned"/>
</id>

The generator class is set to -assigned- which means that hibernate will require you to create the primary key value for your entity.

Change this value for something else (increment, hilo etc), or set the id on the entity before persisting it.

Have a good day :)


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 09, 2005 1:08 pm 
Senior
Senior

Joined: Tue Feb 08, 2005 5:26 pm
Posts: 157
Location: Montréal, Québec - Canada
I think it would be easier for you to let the database decide on the primary key for the adress table. There is no need for sharing identical ids on both tables.

If your relation is one-to-one, the employee will retain the value of the Employee ID field.

If you really want to synchronize IDs, you can use an Interceptor and put the ID when it's called. But, again, I think it would be better if you would let the database manage its keys.

Good luck ;)
Vincent.

_________________
Vincent Giguère
J2EE Developer


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 10, 2005 5:56 am 
Newbie

Joined: Mon May 09, 2005 7:48 am
Posts: 5
Can anyone expand further on this? I always thought it to be a good database design pattern to have a Parent table with a generated PK, and several child tables (having a one-to-one relationship), all having their PK as the FK of the Parent table.

Are you said each of the child tables should have a unique ID, and another column for the FK of the Parent table. Surely this impact on performance, as the PK is indexed, but the FK is searched upon most often.


vgiguere wrote:
I think it would be easier for you to let the database decide on the primary key for the adress table. There is no need for sharing identical ids on both tables.

If your relation is one-to-one, the employee will retain the value of the Employee ID field.

If you really want to synchronize IDs, you can use an Interceptor and put the ID when it's called. But, again, I think it would be better if you would let the database manage its keys.

Good luck ;)
Vincent.


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 10, 2005 10:52 am 
Senior
Senior

Joined: Tue Feb 08, 2005 5:26 pm
Posts: 157
Location: Montréal, Québec - Canada
I am not a database specialist, so I do not know if you would really gain performance from having a join between two tables based on child.id = parent.id, rather than just having a parent.fk on the child.id.

Anyways, I believe that if you change your one-to-one mapping to <generator class="increment"/>, your ID should be populated automatically by hibernate. (I am not sure though, I always use another type of mapping through a foreigh key)

Code:
<many-to-one unique="true" name="address" column="address_fk" class="org.appfuse.model.EmployeesAddress"></many-to-one>


Let me know if you managed to have the key assigned automatically.

Good luck,
Vincent.

_________________
Vincent Giguère
J2EE Developer


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 10, 2005 11:50 am 
Senior
Senior

Joined: Tue Feb 08, 2005 5:26 pm
Posts: 157
Location: Montréal, Québec - Canada
I found this is the documentation at chapter 6.1.4.1. Generator:

Quote:
foreign - uses the identifier of another associated object. Usually used in conjunction with a <one-to-one> primary key association.


This would probably solve your problem.

Good luck :)[/code]

_________________
Vincent Giguère
J2EE Developer


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 10, 2005 11:51 am 
Senior
Senior

Joined: Tue Feb 08, 2005 5:26 pm
Posts: 157
Location: Montréal, Québec - Canada
I found this is the documentation at chapter 6.1.4.1. Generator:

Quote:
foreign - uses the identifier of another associated object. Usually used in conjunction with a <one-to-one> primary key association.


This would probably solve your problem.

Good luck :)[/code]

_________________
Vincent Giguère
J2EE Developer


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.