-->
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.  [ 3 posts ] 
Author Message
 Post subject: help with one-to-one primary key association
PostPosted: Mon Feb 20, 2006 4:01 pm 
Newbie

Joined: Mon Feb 20, 2006 3:47 pm
Posts: 2
I'm working with the "Hibernate In Action" book and Hibernate3.

I have an existing database with two tables as follows:

Table SCAN_RESULT
Primary Key EXP_NAME (varchar2)
Column LOT_NUMBER (varchar2)

Table SCAN_QC
Primary Key EXP_NAME (varchar2) **
Column PASS_FAIL (varchar2)
Column COMMENTS (varchar2)
** Foreign key constraint to SCAN_RESULT.EXP_NAME


I modeled this with the following two mapping files

ScanResult.hbm.xml
<hibernate-mapping>
<class name="ScanResult" table="SCAN_RESULT">
<id name="exp_name" column="EXP_NAME"/>
<property name="lot_number"/>
<one-to-one name="scan_qc"
class="ScanQC"
cascade="save-update" />
</class>
</hibernate-mapping>

ScanQC.hbm.xml
<hibernate-mapping>

<class name="ScanQC" table="SCAN_QC">
<id name="exp_name" column="EXP_NAME">
<generator class="foreign">
<param name="property">scan_result</param>
</generator>
</id>
<property name="pass_fail"/>
<property name="comments"/>

<one-to-one name="scan_result"
class="ScanResult"
constrained="true"/>

</class>
</hibernate-mapping>

So far I have not had any problems retrieving results from the database.

Now, I have an example where I fetch a ScanResult with a null ScanQC, then do the following

ScanQC sqc = new ScanQC();
sqc.setPass_fail("pass");
scan_result.setScan_qc(sqc);
HibernateUtil.commitTransaction();

at which point the following is reported ...

Exception in thread "main" org.hibernate.HibernateException: org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property: scan_result
at com.genelogic.qcwb.hibernate.HibernateUtil.commitTransaction(HibernateUtil.java:70)
at test.hibernate.Main.run(Main.java:68)
at test.hibernate.Main.main(Main.java:131)
Caused by: org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property: scan_result
at org.hibernate.id.ForeignGenerator.generate(ForeignGenerator.java:38)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:85)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:184)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:173)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:96)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:69)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:468)
at org.hibernate.engine.Cascades$5.cascade(Cascades.java:154)
at org.hibernate.engine.Cascades.cascadeAssociation(Cascades.java:771)
at org.hibernate.engine.Cascades.cascade(Cascades.java:720)
at org.hibernate.engine.Cascades.cascade(Cascades.java:847)
at org.hibernate.event.def.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:121)
at org.hibernate.event.def.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:112)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:59)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:730)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:324)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:86)
at com.genelogic.qcwb.hibernate.HibernateUtil.commitTransaction(HibernateUtil.java:66)
... 2 moreException in thread "main" org.hibernate.HibernateException: org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property: scan_result
at com.genelogic.qcwb.hibernate.HibernateUtil.commitTransaction(HibernateUtil.java:70)
at test.hibernate.Main.run(Main.java:68)
at test.hibernate.Main.main(Main.java:131)
Caused by: org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property: scan_result
at org.hibernate.id.ForeignGenerator.generate(ForeignGenerator.java:38)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:85)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:184)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:173)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:96)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:69)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:468)
at org.hibernate.engine.Cascades$5.cascade(Cascades.java:154)
at org.hibernate.engine.Cascades.cascadeAssociation(Cascades.java:771)
at org.hibernate.engine.Cascades.cascade(Cascades.java:720)
at org.hibernate.engine.Cascades.cascade(Cascades.java:847)
at org.hibernate.event.def.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:121)
at org.hibernate.event.def.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:112)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:59)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:730)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:324)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:86)
at com.genelogic.qcwb.hibernate.HibernateUtil.commitTransaction(HibernateUtil.java:66)


Any help is greatly appreciated.


Top
 Profile  
 
 Post subject: resolution
PostPosted: Mon Feb 20, 2006 5:29 pm 
Newbie

Joined: Mon Feb 20, 2006 3:47 pm
Posts: 2
... just gotta love hibernate ...

The following simple solution fixed my problem. My POJOs didn't have any "scaffolding" code. I needed to establish the two-way associations. The code below did the trick --

// scan_result given from before
ScanQC sqc = new ScanQC();
sqc.setPass_fail("pass");
sqc.setScan_result(scan_result);
scan_result.setScan_qc(sqc);

HibernateUtil.commitTransaction();


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 20, 2006 8:36 pm 
Newbie

Joined: Mon Feb 20, 2006 7:45 pm
Posts: 1
I know you posted this asking for help but since you seemed to have figured it out, do you think you could help me? I didn't really want to create another topic on exactly the same subject.

I'm trying to follow the example in the Hibernate documentation where there's two classes, Employee and Person, where each Employee needs access to a Person object.

This is what I have so far...
Note - Hibernate-mapping tags are there, I just didn't copy them

Employee.hbm.xml
Code:
<class name="members.Employee" table="EMPLOYEE">
   <id name="id" column="EMPLOYEE_ID">
      <generator class="native"/>
   </id>
      
   <property name="job" />
      
   <one-to-one name="person" class="members.Person" cascade="save-update"/>
</class>


The Employee.java instance variables are
private Long id;
private String job;
private Person person;


Person.hbm.xml
Code:
<class name="members.Person" table="PERSON">
   <id name="id" column="EMPLOYEE_ID">
      <generator class="foreign">
         <param name="property">employee</param>
      </generator>
   </id>
   
   <property name="name" />
   
   <one-to-one name="employee" class="members.Employee" constrained="true"/>
</class>


The Person.java instance variables are
private Long id;
private String name;
private Employee employee;


I'm calling this method and only this method right now to test it.

Code:
public Long addEmployee(String job){
   Session session = HibernateUtil.getSessionFactory().getCurrentSession();
   session.beginTransaction();
   
   Employee e = new Employee();   
   e.setJob(job);      
   session.save(e);

   Person p = new Person();   
   p.setName("A name");
   p.setEmployee(e);
   e.setPerson(p);
   
   session.getTransaction().commit();
   
   return e.getId();
}


When I run it I get a series of statements creating the tables (I have the drop/recreate enabled) followed by:
Hibernate: insert into EMPLOYEE (job, EMPLOYEE_ID) values (?, null)
Hibernate: call identity()
Hibernate: insert into PERSON (name, EMPLOYEE_ID) values (?, ?)
19:21:07,741 WARN JDBCExceptionReporter:71 - SQL Error: -28, SQLState: S0022
19:21:07,751 ERROR JDBCExceptionReporter:72 - Column not found: NAME in statement [insert into PERSON (name, EMPLOYEE_ID) values (?, ?)]
Exception in thread "main" org.hibernate.exception.SQLGrammarException: could not insert: [members.Person]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:65)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2078)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2427)
at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:51)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:243)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:227)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:140)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:296)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1007)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:354)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at members.MemberManager.addEmployee(MemberManager.java:72)
at members.MemberManager.main(MemberManager.java:21)
Caused by: java.sql.SQLException: Column not found: NAME in statement [insert into PERSON (name, EMPLOYEE_ID) values (?, ?)]
at org.hsqldb.jdbc.Util.throwError(Unknown Source)
at org.hsqldb.jdbc.jdbcPreparedStatement.<init>(Unknown Source)
at org.hsqldb.jdbc.jdbcConnection.prepareStatement(Unknown Source)
at org.hibernate.jdbc.AbstractBatcher.getPreparedStatement(AbstractBatcher.java:442)
at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:93)
at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:86)
at org.hibernate.jdbc.AbstractBatcher.prepareBatchStatement(AbstractBatcher.java:171)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2048)
... 12 more
19:21:07,761 ERROR AbstractFlushingEventListener:299 - Could not synchronize database state with session
org.hibernate.exception.SQLGrammarException: could not insert: [members.Person]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:65)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2078)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2427)
at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:51)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:243)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:227)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:140)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:296)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1007)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:354)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at members.MemberManager.addEmployee(MemberManager.java:72)
at members.MemberManager.main(MemberManager.java:21)
Caused by: java.sql.SQLException: Column not found: NAME in statement [insert into PERSON (name, EMPLOYEE_ID) values (?, ?)]
at org.hsqldb.jdbc.Util.throwError(Unknown Source)
at org.hsqldb.jdbc.jdbcPreparedStatement.<init>(Unknown Source)
at org.hsqldb.jdbc.jdbcConnection.prepareStatement(Unknown Source)
at org.hibernate.jdbc.AbstractBatcher.getPreparedStatement(AbstractBatcher.java:442)
at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:93)
at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:86)
at org.hibernate.jdbc.AbstractBatcher.prepareBatchStatement(AbstractBatcher.java:171)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2048)
... 12 more


I'm completely lost as to what to do here. I've spent probably 8+ hours looking over various help sites and testing random tag changes, but I can't get it to work. If I remove the part attaching the Person object and just save an employee with a job it works, and it'll give me an ID, but when I try to retrieve the "job" value using that ID I get "could not load an entity: [members.Employee#1]".

If you (or anyone else reading this) could help me I would greatly appreciate it. Getting many-to-many to work was relatively easy but one-to-one seems impossible right now.


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