-->
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.  [ 11 posts ] 
Author Message
 Post subject: 1-to-1 with primary key association won't insert children
PostPosted: Fri Nov 19, 2004 9:43 pm 
Regular
Regular

Joined: Wed Sep 10, 2003 2:26 pm
Posts: 56
Location: San Diego, CA
I know I'm doing something stupid, but can't figure out what. Please help.

here's the parent's mapping:
Code:
<hibernate-mapping>
   <class name="edu.ucsd.som.salpro.model.SalProEmployee" table="salpro_employee">
      <id name="id" column="salpro_employee_id" type="long">
         <generator class="native"/>
      </id>

      <property name="fullName" column="full_name" not-null="true" type="string" />
      <property name="homeDepartmentCode" column="home_department_id" type="int" access="field" update="false" insert="false"/>
      <property name="employeeId" column="ucsd_id" type="string"/>

      <many-to-one name="homeDepartment" column="home_department_id" class="edu.ucsd.som.salpro.model.SalProDepartment" outer-join="false"/>
      <one-to-one name="appointment" class="edu.ucsd.som.salpro.model.Appointment" cascade="all" access="field" />

      <set name="divisions" lazy="true" table="salpro_employee_division">
         <key column="employee_id"/>
         <many-to-many class="edu.ucsd.som.salpro.model.SalProDivision" column="division_id"/>
      </set>

   </class>
</hibernate-mapping>

and the child's mapping:
Code:
<hibernate-mapping>
   <class name="edu.ucsd.som.salpro.model.Appointment" table="salpro_appointment">
      <id name="_id" column="appointment_id" type="long">
<!--         <generator class="native"/>-->
         <generator class="foreign">
            <param name="property">employee</param>
         </generator>
      </id>

      <property name="onScale" column="on_scale" type="boolean" />
      <one-to-one name="employee" class="edu.ucsd.som.salpro.model.SalProEmployee" constrained="true"/>
      <many-to-one name="apuCode" column="apu_code" class="edu.ucsd.som.salpro.model.ApuCode"/>
   </class>
</hibernate-mapping>

When I do this:
Code:
      Appointment app = new Appointment();
      SalProEmployee emp = new SalProEmployee();

      app.setEmployee(emp);

      PersistentObject.save(app);


what I get is a new record in the employee table, but no new record in the appointment table.

Now, if I go into Appointment.hbm.xml and change <id> from foreign to native, then an appointment record does get inserted, but the primary key value is not, obviously, syncrhoized with the parent's primary key.

What am I doing wrong?


Hibernate version:
2.1.3

Mapping documents:
see above

Code between sessionFactory.openSession() and session.close():
see above

Full stack trace of any exception that occurs:
n/a

Name and version of the database you are using:
mysql 3.1.xx

The generated SQL (show_sql=true):
see below

Debug level Hibernate log excerpt:
...
[main] DEBUG net.sf.hibernate.impl.SessionFactoryImpl - instantiated session factory
Hibernate factory inited
[main] DEBUG net.sf.hibernate.impl.SessionImpl - opened session
Openning Hibernate session net.sf.hibernate.impl.SessionImpl@1e7c5cb
[main] DEBUG net.sf.hibernate.impl.SessionImpl - saveOrUpdate() unsaved instance
[main] DEBUG net.sf.hibernate.impl.SessionImpl - saving [edu.ucsd.som.salpro.model.SalProEmployee#<null>]
[main] DEBUG net.sf.hibernate.impl.SessionImpl - executing insertions
[main] DEBUG net.sf.hibernate.engine.Cascades - processing cascades for: edu.ucsd.som.salpro.model.SalProEmployee
[main] DEBUG net.sf.hibernate.engine.Cascades - done processing cascades for: edu.ucsd.som.salpro.model.SalProEmployee
[main] DEBUG net.sf.hibernate.impl.WrapVisitor - Wrapped collection in role: edu.ucsd.som.salpro.model.SalProEmployee.divisions
[main] DEBUG net.sf.hibernate.engine.Cascades - id unsaved-value strategy NULL
[main] DEBUG net.sf.hibernate.persister.EntityPersister - Inserting entity: edu.ucsd.som.salpro.model.SalProEmployee (native id)
[main] DEBUG net.sf.hibernate.impl.BatcherImpl - about to open: 0 open PreparedStatements, 0 open ResultSets
[main] DEBUG net.sf.hibernate.SQL - insert into salpro_employee (full_name, ucsd_id, home_department_id) values (?, ?, ?)
[main] DEBUG net.sf.hibernate.impl.BatcherImpl - preparing statement
[main] DEBUG net.sf.hibernate.persister.EntityPersister - Dehydrating entity: [edu.ucsd.som.salpro.model.SalProEmployee#<null>]
[main] DEBUG net.sf.hibernate.type.StringType - binding 'Jonny Smith' to parameter: 1
[main] DEBUG net.sf.hibernate.type.StringType - binding null to parameter: 2
[main] DEBUG net.sf.hibernate.engine.Cascades - id unsaved-value strategy NULL
[main] DEBUG net.sf.hibernate.type.StringType - binding '34' to parameter: 3
[main] DEBUG net.sf.hibernate.persister.AbstractEntityPersister - Natively generated identity: 2
[main] DEBUG net.sf.hibernate.impl.BatcherImpl - done closing: 0 open PreparedStatements, 0 open ResultSets
[main] DEBUG net.sf.hibernate.impl.BatcherImpl - closing statement
[main] DEBUG net.sf.hibernate.engine.Cascades - processing cascades for: edu.ucsd.som.salpro.model.SalProEmployee
[main] DEBUG net.sf.hibernate.engine.Cascades - cascading to saveOrUpdate()
[main] DEBUG net.sf.hibernate.impl.SessionImpl - saveOrUpdate() unsaved instance
[main] DEBUG net.sf.hibernate.impl.SessionImpl - generated identifier: 2
[main] DEBUG net.sf.hibernate.impl.SessionImpl - saving [edu.ucsd.som.salpro.model.Appointment#2]
[main] DEBUG net.sf.hibernate.engine.Cascades - done processing cascades for: edu.ucsd.som.salpro.model.SalProEmployee


Top
 Profile  
 
 Post subject:
PostPosted: Sat Nov 20, 2004 7:09 am 
Regular
Regular

Joined: Fri Jul 16, 2004 3:04 pm
Posts: 52
Location: Wiltshire UK
Hi, I think the problem may be becasue you are saving the Appointment which has no cascade set, so it will not save the Employee. Try saving the Employee, or adding a cascade to the Appointment mapping.

HTH

Paul :-)


Top
 Profile  
 
 Post subject:
PostPosted: Sat Nov 20, 2004 2:50 pm 
Regular
Regular

Joined: Wed Sep 10, 2003 2:26 pm
Posts: 56
Location: San Diego, CA
Doh! You're right. But this doesn't change anything. That code was just a simplyfied version of the real code (which has correct logic). Here's a corrected version:

Code:
      Appointment app = new Appointment();
      SalProEmployee emp = new SalProEmployee();

      emp.setFullName("Jonny Smith");
      app.setEmployee(emp);
      emp.setAppointment(app);
      PersistentObject.save(emp);


the end result is the same as before: a new Employee record is created in the employee table, but no appointment record is created in the appointment table.

A bigger question is: what conditions may prevent appointment data from getting persisted? (keeping in mind that no exceptions are thrown and the debug trace contains no errors/warnings)


Top
 Profile  
 
 Post subject:
PostPosted: Sat Nov 20, 2004 3:19 pm 
Regular
Regular

Joined: Fri Jul 16, 2004 3:04 pm
Posts: 52
Location: Wiltshire UK
Hi looking at the example in Hibernate in Action (if you have the book, it's page 220 onwards, if you don't & you're serious about Hibernate, then you need it!), you need to map one end of the relationship with a many-to-one mapping with a unique="true" attribute!! Yes weird & counter-intuitive, but that's how it seems to work.

You'll have to work out which end of the relationship you want to map as many-to-one (I'm not sure if it matters), but for example yours could look like this.

Code:
in employee<many-to-one name="appointment" class="edu.ucsd.som.salpro.model.Appointment" cascade="all" access="field" unique="true"/>


Code:
in appointment<one-to-one name="employee" class="edu.ucsd.som.salpro.model.SalProEmployee" property-ref="appointment">


This would give you a bi-directional relationship.

Give this a try
Paul :-)


Top
 Profile  
 
 Post subject:
PostPosted: Sat Nov 20, 2004 3:32 pm 
Regular
Regular

Joined: Fri Jul 16, 2004 3:04 pm
Posts: 52
Location: Wiltshire UK
Oops, just looked again & realized that you are using primary-Key mapping not foreign-key mapping!! Sorry :-)

I think the problem is the generator class in your employee. It shouldn't be native, but should be
Code:
<generator class="foreign">
         <param name="property">employee</param>
</generator>


HTH
Paul


Top
 Profile  
 
 Post subject:
PostPosted: Sat Nov 20, 2004 5:30 pm 
Regular
Regular

Joined: Wed Sep 10, 2003 2:26 pm
Posts: 56
Location: San Diego, CA
javacoda wrote:
Oops, just looked again & realized that you are using primary-Key mapping not foreign-key mapping!! Sorry :-)

I think the problem is the generator class in your employee. It shouldn't be native, but should be
Code:
<generator class="foreign">
         <param name="property">employee</param>
</generator>


HTH
Paul


Paul, but the employee's id is not a foreign key, it's the table's primary key. Now, i agree that the appointment's id is a foreign key into the employee table, and that's how I have these two mapped.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Nov 21, 2004 6:01 pm 
Regular
Regular

Joined: Fri Jul 16, 2004 3:04 pm
Posts: 52
Location: Wiltshire UK
Oops sorry again! Late night posting isn't good, I didn't notice that you had commented out the "native" line & added a foreign generator underneath.

Are you sure no appointment record is being persisted to the database
this line
[main] DEBUG net.sf.hibernate.impl.SessionImpl - saving [edu.ucsd.som.salpro.model.Appointment#2] would appear to indicate that an appointment record is being saved??

Also can you show the code for your PersistentObject.save() method.

Paul :-)


Top
 Profile  
 
 Post subject:
PostPosted: Sun Nov 21, 2004 8:56 pm 
Regular
Regular

Joined: Wed Sep 10, 2003 2:26 pm
Posts: 56
Location: San Diego, CA
javacoda wrote:
Are you sure no appointment record is being persisted to the database
this line
[main] DEBUG net.sf.hibernate.impl.SessionImpl - saving [edu.ucsd.som.salpro.model.Appointment#2] would appear to indicate that an appointment record is being saved??


This is the most puzzling part of the problem. Yes, i've checked over and over :) and nothing is being saved. I'm using DBUnit for testing, so it's easy to see when anything is being created. At the moment the table is emply.

Also, i have show_sql enabed and I can see in the trace the sql statement used for inserting a new employee record.

Code:
[main] DEBUG net.sf.hibernate.SQL - insert into salpro_employee (full_name, ucsd_id, home_department_id) values (?, ?, ?)


Yet, an sql statement for inserting an appointment is conspicuously missing from the trace. Which tells me that Hibernate never actually generates and sends a query to the database. Weird. WHy?

Here's the code for the save() method:

Code:
   public void save(Object object ) throws DataStoreException
   {
      Session session = null;

      try
      {
         session = getSession();
         session.saveOrUpdate(object);
      }
      catch(HibernateException e)
      {
         throw new DataStoreLoadException(e);
      }
   }


this function is used through out multiple production applications and i've not had any problems with it.

Dmitry

PS. Thanks for your help so far, Paul


Top
 Profile  
 
 Post subject: Re: 1-to-1 with primary key association won't insert childre
PostPosted: Mon Nov 22, 2004 5:02 am 
Beginner
Beginner

Joined: Wed Feb 25, 2004 5:54 am
Posts: 30
dberansky wrote:
I know I'm doing something stupid, but can't figure out what. Please help.

here's the parent's mapping:
Code:
<hibernate-mapping>
   <class name="edu.ucsd.som.salpro.model.SalProEmployee" table="salpro_employee">
      <id name="id" column="salpro_employee_id" type="long">
         <generator class="native"/>
      </id>

      <property name="fullName" column="full_name" not-null="true" type="string" />
      <property name="homeDepartmentCode" column="home_department_id" type="int" access="field" update="false" insert="false"/>
      <property name="employeeId" column="ucsd_id" type="string"/>

      <many-to-one name="homeDepartment" column="home_department_id" class="edu.ucsd.som.salpro.model.SalProDepartment" outer-join="false"/>
      <one-to-one name="appointment" class="edu.ucsd.som.salpro.model.Appointment" cascade="all" access="field" />

      <set name="divisions" lazy="true" table="salpro_employee_division">
         <key column="employee_id"/>
         <many-to-many class="edu.ucsd.som.salpro.model.SalProDivision" column="division_id"/>
      </set>

   </class>
</hibernate-mapping>

and the child's mapping:
Code:
<hibernate-mapping>
   <class name="edu.ucsd.som.salpro.model.Appointment" table="salpro_appointment">
      <id name="_id" column="appointment_id" type="long">
<!--         <generator class="native"/>-->
         <generator class="foreign">
            <param name="property">employee</param>
         </generator>
      </id>

      <property name="onScale" column="on_scale" type="boolean" />
      <one-to-one name="employee" class="edu.ucsd.som.salpro.model.SalProEmployee" constrained="true"/>
      <many-to-one name="apuCode" column="apu_code" class="edu.ucsd.som.salpro.model.ApuCode"/>
   </class>
</hibernate-mapping>

When I do this:
Code:
      Appointment app = new Appointment();
      SalProEmployee emp = new SalProEmployee();

      app.setEmployee(emp);

      PersistentObject.save(app);


what I get is a new record in the employee table, but no new record in the appointment table.

Now, if I go into Appointment.hbm.xml and change <id> from foreign to native, then an appointment record does get inserted, but the primary key value is not, obviously, syncrhoized with the parent's primary key.

What am I doing wrong?


Hibernate version:
2.1.3

Mapping documents:
see above

Code between sessionFactory.openSession() and session.close():
see above

Full stack trace of any exception that occurs:
n/a

Name and version of the database you are using:
mysql 3.1.xx

The generated SQL (show_sql=true):
see below

Debug level Hibernate log excerpt:
...
[main] DEBUG net.sf.hibernate.impl.SessionFactoryImpl - instantiated session factory
Hibernate factory inited
[main] DEBUG net.sf.hibernate.impl.SessionImpl - opened session
Openning Hibernate session net.sf.hibernate.impl.SessionImpl@1e7c5cb
[main] DEBUG net.sf.hibernate.impl.SessionImpl - saveOrUpdate() unsaved instance
[main] DEBUG net.sf.hibernate.impl.SessionImpl - saving [edu.ucsd.som.salpro.model.SalProEmployee#<null>]
[main] DEBUG net.sf.hibernate.impl.SessionImpl - executing insertions
[main] DEBUG net.sf.hibernate.engine.Cascades - processing cascades for: edu.ucsd.som.salpro.model.SalProEmployee
[main] DEBUG net.sf.hibernate.engine.Cascades - done processing cascades for: edu.ucsd.som.salpro.model.SalProEmployee
[main] DEBUG net.sf.hibernate.impl.WrapVisitor - Wrapped collection in role: edu.ucsd.som.salpro.model.SalProEmployee.divisions
[main] DEBUG net.sf.hibernate.engine.Cascades - id unsaved-value strategy NULL
[main] DEBUG net.sf.hibernate.persister.EntityPersister - Inserting entity: edu.ucsd.som.salpro.model.SalProEmployee (native id)
[main] DEBUG net.sf.hibernate.impl.BatcherImpl - about to open: 0 open PreparedStatements, 0 open ResultSets
[main] DEBUG net.sf.hibernate.SQL - insert into salpro_employee (full_name, ucsd_id, home_department_id) values (?, ?, ?)
[main] DEBUG net.sf.hibernate.impl.BatcherImpl - preparing statement
[main] DEBUG net.sf.hibernate.persister.EntityPersister - Dehydrating entity: [edu.ucsd.som.salpro.model.SalProEmployee#<null>]
[main] DEBUG net.sf.hibernate.type.StringType - binding 'Jonny Smith' to parameter: 1
[main] DEBUG net.sf.hibernate.type.StringType - binding null to parameter: 2
[main] DEBUG net.sf.hibernate.engine.Cascades - id unsaved-value strategy NULL
[main] DEBUG net.sf.hibernate.type.StringType - binding '34' to parameter: 3
[main] DEBUG net.sf.hibernate.persister.AbstractEntityPersister - Natively generated identity: 2
[main] DEBUG net.sf.hibernate.impl.BatcherImpl - done closing: 0 open PreparedStatements, 0 open ResultSets
[main] DEBUG net.sf.hibernate.impl.BatcherImpl - closing statement
[main] DEBUG net.sf.hibernate.engine.Cascades - processing cascades for: edu.ucsd.som.salpro.model.SalProEmployee
[main] DEBUG net.sf.hibernate.engine.Cascades - cascading to saveOrUpdate()
[main] DEBUG net.sf.hibernate.impl.SessionImpl - saveOrUpdate() unsaved instance
[main] DEBUG net.sf.hibernate.impl.SessionImpl - generated identifier: 2
[main] DEBUG net.sf.hibernate.impl.SessionImpl - saving [edu.ucsd.som.salpro.model.Appointment#2]
[main] DEBUG net.sf.hibernate.engine.Cascades - done processing cascades for: edu.ucsd.som.salpro.model.SalProEmployee



Have you tried using unsaved value?? Try the following..hope this helps.
(Parent mapping)
<id name="id" column="salpro_employee_id" type="long" unsaved-value="null">


(Child mapping)
<id name="_id" column="appointment_id" type="long" unsaved-value="null">


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 23, 2004 1:14 pm 
Regular
Regular

Joined: Wed Sep 10, 2003 2:26 pm
Posts: 56
Location: San Diego, CA
"unsaved-value" is null by default. this isn't it :(


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 23, 2004 3:54 pm 
Regular
Regular

Joined: Fri Jul 16, 2004 3:04 pm
Posts: 52
Location: Wiltshire UK
Are you closing the sesion anywhere? Your method doesn't seem to do this (maybe as you've only shown part of the code). I think that you should close the session, but the problem may be that as you are not using transactions (why not?), you probably need to call session.flush() before closing the session.

Paul :-)


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