-->
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.  [ 10 posts ] 
Author Message
 Post subject: How to save parent-child in one-to-many association?
PostPosted: Mon Feb 23, 2004 4:16 am 
Regular
Regular

Joined: Wed Dec 03, 2003 9:41 pm
Posts: 87
Exception when save method called.
Exception:
Code:
Hibernate: insert into de_purchase_order (PO_NO, INVOICE_NO, ORDER_DATE, CUSTORMS_DECLARATION_NO) values (?, ?, ?, ?)

Hibernate: select @@identity

Hibernate: update de_purchase_order_line set PURC_ORDER_ID=? where id=?

2004-02-23 16:15:17,023(2453) [main] ERROR net.sf.hibernate.impl.SessionImpl  - Could not synchronize database state with session

net.sf.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.dealeasy.ems.monitor.table.DePurchaseOrderLineModel

   at net.sf.hibernate.impl.SessionImpl.throwTransientObjectException(SessionImpl.java:2647)

   at net.sf.hibernate.impl.SessionImpl.getEntityIdentifierIfNotUnsaved(SessionImpl.java:2639)

   at net.sf.hibernate.type.EntityType.getIdentifier(EntityType.java:66)

   at net.sf.hibernate.type.ManyToOneType.nullSafeSet(ManyToOneType.java:46)

   at net.sf.hibernate.collection.AbstractCollectionPersister.writeElement(AbstractCollectionPersister.java:386)

   at net.sf.hibernate.collection.Set.writeTo(Set.java:228)

   at net.sf.hibernate.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:539)

   at net.sf.hibernate.impl.ScheduledCollectionRecreate.execute(ScheduledCollectionRecreate.java:23)

   at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2303)

   at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2260)

   at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2182)

   at com.dealeasy.ems.monitor.business.BusinessObject.commitTransaction(BusinessObject.java:46)

   at com.dealeasy.ems.monitor.business.PurchaseOrder.addPO(PurchaseOrder.java:77)

   at com.dealeasy.ems.monitor.business.TestPurchaseOrder.testAddPO(TestPurchaseOrder.java:58)

   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

   at java.lang.reflect.Method.invoke(Method.java:324)

   at junit.framework.TestCase.runTest(TestCase.java:154)

   at junit.framework.TestCase.runBare(TestCase.java:127)

   at junit.framework.TestResult$1.protect(TestResult.java:106)

   at junit.framework.TestResult.runProtected(TestResult.java:124)

   at junit.framework.TestResult.run(TestResult.java:109)

   at junit.framework.TestCase.run(TestCase.java:118)

   at junit.framework.TestSuite.runTest(TestSuite.java:208)

   at junit.framework.TestSuite.run(TestSuite.java:203)

   at com.borland.jbuilder.unittest.JBTestRunner.run(JBTestRunner.java:206)

   at com.borland.jbuilder.unittest.JBTestRunner.initiateTest(JBTestRunner.java:248)

   at com.borland.jbuilder.unittest.JBTestRunner.main(JBTestRunner.java:554)


Fragment of hbm.xml :
Code:
   <set name="poLines" lazy="false" outer-join="true" cascade="none">
      <key column="PURC_ORDER_ID"/>
      <one-to-many class="com.dealeasy.ems.monitor.table.DePurchaseOrderLineModel"/>
   </set>


Fragment of insert code :
Code:
      DePurchaseOrderModel insertModel = new DePurchaseOrderModel();
      insertModel.setInvoiceNo("222");
      insertModel.setPoNo("111");
      DePurchaseOrderLineModel line1 = new DePurchaseOrderLineModel();
      line1.setDescription("dsfd");
      line1.setUnitPrice(new Double(34.32));

      DePurchaseOrderLineModel line2 = new DePurchaseOrderLineModel();
      line2.setDescription("gfhgf");
      line2.setUnitPrice(new Double(56.31));

      Set setLine = new HashSet();
      setLine.add(line1);
      setLine.add(line2);
      insertModel.setPoLines(setLine);
      ...
      Session s = super.currentSession();
      s.save(obj);


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 23, 2004 9:58 am 
Regular
Regular

Joined: Mon Nov 24, 2003 6:36 pm
Posts: 105
try changing cascade to something other than none.

Make sure your child knows how to generate an identifier.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 23, 2004 10:38 pm 
Regular
Regular

Joined: Wed Dec 03, 2003 9:41 pm
Posts: 87
I found the root reason. Column PURC_ORDER_ID of child table is stored PK of parent table. In hbm.xml, I config it not-null="true". When I save parent object (include a set of children), hibernate check this column shouldn't be null. It throws Exception:

Code:
net.sf.hibernate.PropertyValueException: not-null property references a null or transient value: net.sf.hibernate.persister.EntityPersister.purcOrderId


If I get rid of not-null="true", it throws Exception:

Code:
Caused by: java.sql.SQLException: [Microsoft][SQLServer JDBC Driver][SQLServer]Cannot insert the value NULL into column 'PURC_ORDER_ID', table 'ems_monitor.dbo.de_purchase_order_line'; column does not allow nulls. INSERT fails.


I used MSSQL Server 2000 and the PK of parent table and child table is both identity. I think PK is ok. But why hibernate doesn't put new PK of parent to column PURC_ORDER_ID of child table ?
How shoud I do?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 23, 2004 11:26 pm 
Regular
Regular

Joined: Mon Nov 24, 2003 6:36 pm
Posts: 105
Suggestions:
read this - i think it applies
http://www.hibernate.org/155.html

If you have foreign key constraints in the child table, then you must set inverse=true on the collection. That is not the case in the mapping you showed us. You will need not null = true in the child.

You have to set parent on the child before saving eg.
child.setParent(parent)



Re-read the manual on parent child relationships, and the faq section.

Good luck
James


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 24, 2004 1:28 am 
Regular
Regular

Joined: Wed Dec 03, 2003 9:41 pm
Posts: 87
Yes, I call setParent method. Exception thrown when insert children.
I only config one-to-many association, not include many-to-one.
The following is my hbm.xml:

Code:
<hibernate-mapping>
<class name="com.dealeasy.ems.monitor.table.DePurchaseOrderModel" table="de_purchase_order">
<id column="id" name="id" type="java.lang.Long">
<generator class="identity"/>
</id>
<property column="PO_NO" length="15" name="poNo" not-null="true" type="java.lang.String"/>
<property column="INVOICE_NO" length="15" name="invoiceNo" type="java.lang.String"/>
<property column="ORDER_DATE" length="23" name="orderDate" type="java.util.Date"/>
<property column="CUSTORMS_DECLARATION_NO" length="80" name="custormsDeclarationNo" type="java.lang.String"/>
   <set name="poLines" lazy="false" cascade="save-update" inverse="true">
      <key column="PURC_ORDER_ID"/>
      <one-to-many class="com.dealeasy.ems.monitor.table.DePurchaseOrderLineModel"/>
   </set>
</class>
<class name="com.dealeasy.ems.monitor.table.DePurchaseOrderLineModel" table="de_purchase_order_line">
<id column="id" name="id" type="java.lang.Long">
<generator class="identity"/>
</id>
<property column="PURC_ORDER_ID" length="15" name="purcOrderId" not-null="true" type="java.lang.Long"/>
<property column="PART_ID" length="15" name="partId" not-null="true" type="java.lang.String"/>
<property column="DESCRIPTION" length="40" name="description" type="java.lang.String"/>
<property column="ORDER_QTY" length="14" name="orderQty" type="java.lang.Double"/>
<property column="UNIT_PRICE" length="15" name="unitPrice" type="java.lang.Double"/>
<property column="TOTAL_SUM" length="18" name="totalSum" type="java.lang.Long"/>
</class>
</hibernate-mapping>

Must I config many-to-one association in child?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 24, 2004 1:31 am 
Regular
Regular

Joined: Wed Dec 03, 2003 9:41 pm
Posts: 87
More detail exception is the following:
Code:
Hibernate: insert into de_purchase_order (PO_NO, INVOICE_NO, ORDER_DATE, CUSTORMS_DECLARATION_NO) values (?, ?, ?, ?)

Hibernate: select @@identity

2004-02-24 13:24:41,484(2141) [main] ERROR com.dealeasy.ems.monitor.business.PurchaseOrder  - Exception in PurchaseOrder.addPO

net.sf.hibernate.PropertyValueException: not-null property references a null or transient value: net.sf.hibernate.persister.EntityPersister.purcOrderId

   at net.sf.hibernate.impl.SessionImpl.checkNullability(SessionImpl.java:1206)

   at net.sf.hibernate.impl.SessionImpl.doSave(SessionImpl.java:871)

   at net.sf.hibernate.impl.SessionImpl.doSave(SessionImpl.java:815)

   at net.sf.hibernate.impl.SessionImpl.saveWithGeneratedIdentifier(SessionImpl.java:735)

   at net.sf.hibernate.impl.SessionImpl.save(SessionImpl.java:715)

   at net.sf.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:1317)

   at net.sf.hibernate.engine.Cascades$4.cascade(Cascades.java:114)

   at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:436)

   at net.sf.hibernate.engine.Cascades.cascadeCollection(Cascades.java:526)

   at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:452)

   at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:503)

   at net.sf.hibernate.impl.SessionImpl.doSave(SessionImpl.java:890)

   at net.sf.hibernate.impl.SessionImpl.doSave(SessionImpl.java:815)

   at net.sf.hibernate.impl.SessionImpl.saveWithGeneratedIdentifier(SessionImpl.java:735)

   at net.sf.hibernate.impl.SessionImpl.save(SessionImpl.java:715)

   at com.dealeasy.ems.monitor.dao.DePurchaseOrderDAO.add(DePurchaseOrderDAO.java:35)

   at com.dealeasy.ems.monitor.business.PurchaseOrder.addPO(PurchaseOrder.java:77)

   at com.dealeasy.ems.monitor.business.TestPurchaseOrder.testAddPO(TestPurchaseOrder.java:60)

   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

   at java.lang.reflect.Method.invoke(Method.java:324)

   at junit.framework.TestCase.runTest(TestCase.java:154)

   at junit.framework.TestCase.runBare(TestCase.java:127)

   at junit.framework.TestResult$1.protect(TestResult.java:106)

   at junit.framework.TestResult.runProtected(TestResult.java:124)

   at junit.framework.TestResult.run(TestResult.java:109)

   at junit.framework.TestCase.run(TestCase.java:118)

   at junit.framework.TestSuite.runTest(TestSuite.java:208)

   at junit.framework.TestSuite.run(TestSuite.java:203)

   at com.borland.jbuilder.unittest.JBTestRunner.run(JBTestRunner.java:206)

   at com.borland.jbuilder.unittest.JBTestRunner.initiateTest(JBTestRunner.java:248)

   at com.borland.jbuilder.unittest.JBTestRunner.main(JBTestRunner.java:554)


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 24, 2004 9:08 am 
Regular
Regular

Joined: Mon Nov 24, 2003 6:36 pm
Posts: 105
Quote:
Must I config many-to-one association in child?


Yes, if using inverse="true" your child will need to have a property for the parent.

This is probably why your fk is not being inserted with your child class.

James


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 24, 2004 10:10 pm 
Regular
Regular

Joined: Wed Dec 03, 2003 9:41 pm
Posts: 87
I config many-to-one in child, but it also throws Exception.
hbm.xml
Code:
<hibernate-mapping>
<class name="com.dealeasy.ems.monitor.table.DePurchaseOrderModel" table="de_purchase_order">
<id column="id" name="id" type="java.lang.Long">
<generator class="identity"/>
</id>
<property column="PO_NO" length="15" name="poNo" not-null="true" type="java.lang.String"/>
<property column="INVOICE_NO" length="15" name="invoiceNo" type="java.lang.String"/>
<property column="ORDER_DATE" length="23" name="orderDate" type="java.util.Date"/>
<property column="CUSTORMS_DECLARATION_NO" length="80" name="custormsDeclarationNo" type="java.lang.String"/>
   <set name="poLines" lazy="false" outer-join="true" cascade="save-update" inverse="true">
      <key column="PURC_ORDER_ID"/>
      <one-to-many class="com.dealeasy.ems.monitor.table.DePurchaseOrderLineModel"/>
   </set>
</class>
<class name="com.dealeasy.ems.monitor.table.DePurchaseOrderLineModel" table="de_purchase_order_line">
<id column="id" name="id" type="java.lang.Long">
<generator class="identity"/>
</id>
<many-to-one name="purcOrder" class="com.dealeasy.ems.monitor.table.DePurchaseOrderModel" column="PURC_ORDER_ID"/>
<property column="PART_ID" length="15" name="partId" not-null="true" type="java.lang.String"/>
<property column="DESCRIPTION" length="40" name="description" type="java.lang.String"/>
<property column="ORDER_QTY" length="14" name="orderQty" type="java.lang.Double"/>
<property column="UNIT_PRICE" length="15" name="unitPrice" type="java.lang.Double"/>
<property column="TOTAL_SUM" length="18" name="totalSum" type="java.lang.Double"/>
</class>
</hibernate-mapping>


Insert data:
Code:
      DePurchaseOrderModel insertModel = new DePurchaseOrderModel();
      insertModel.setInvoiceNo("222");
      insertModel.setPoNo("111");
      DePurchaseOrderLineModel line1 = new DePurchaseOrderLineModel();
      line1.setPartId("324-45");
      line1.setDescription("dsfd");
      line1.setUnitPrice(new Double(34.32));

      DePurchaseOrderLineModel line2 = new DePurchaseOrderLineModel();
      line2.setPartId("436-7685");
      line2.setDescription("gfhgf");
      line2.setUnitPrice(new Double(56.31));

      Set setLine = new HashSet();
      setLine.add(line1);
      setLine.add(line2);
      insertModel.setPoLines(setLine);

      purchaseOrder.addPO(insertModel);


Method addPO:

Code:
   public void addPO(DePurchaseOrderModel model) throws DException{
      try{
         beginTransaction();
         Session s = super.currentSession();
         s.save(model);
         commitTransaction();
      } catch(HibernateException ex){
         log.error("Exception in PurchaseOrder.addPO", ex);
         try{
            rollbackTransaction();
         } catch(HibernateException ex1){
         }
      }finally{
         forceReleaseResource();
      }
   }


Hibernate log:
Code:
Hibernate: insert into de_purchase_order (PO_NO, INVOICE_NO, ORDER_DATE, CUSTORMS_DECLARATION_NO) values (?, ?, ?, ?)

Hibernate: select @@identity

Hibernate: insert into de_purchase_order_line (PURC_ORDER_ID, PART_ID, DESCRIPTION, ORDER_QTY, UNIT_PRICE, TOTAL_SUM) values (?, ?, ?, ?, ?, ?)

2004-02-25 09:57:36,562(2109) [main] WARN net.sf.hibernate.util.JDBCExceptionReporter  - SQL Error: 515, SQLState: HY000

2004-02-25 09:57:36,562(2109) [main] ERROR net.sf.hibernate.util.JDBCExceptionReporter  - [Microsoft][SQLServer JDBC Driver][SQLServer]Cannot insert the value NULL into column 'PURC_ORDER_ID', table 'ems_monitor.dbo.de_purchase_order_line'; column does not allow nulls. INSERT fails.

2004-02-25 09:57:36,593(2140) [main] WARN net.sf.hibernate.util.JDBCExceptionReporter  - SQL Error: 3621, SQLState: HY000

2004-02-25 09:57:36,593(2140) [main] ERROR net.sf.hibernate.util.JDBCExceptionReporter  - [Microsoft][SQLServer JDBC Driver][SQLServer]The statement has been terminated.

2004-02-25 09:57:36,593(2140) [main] WARN net.sf.hibernate.util.JDBCExceptionReporter  - SQL Error: 515, SQLState: HY000

2004-02-25 09:57:36,593(2140) [main] ERROR net.sf.hibernate.util.JDBCExceptionReporter  - [Microsoft][SQLServer JDBC Driver][SQLServer]Cannot insert the value NULL into column 'PURC_ORDER_ID', table 'ems_monitor.dbo.de_purchase_order_line'; column does not allow nulls. INSERT fails.

2004-02-25 09:57:36,593(2140) [main] WARN net.sf.hibernate.util.JDBCExceptionReporter  - SQL Error: 3621, SQLState: HY000

2004-02-25 09:57:36,593(2140) [main] ERROR net.sf.hibernate.util.JDBCExceptionReporter  - [Microsoft][SQLServer JDBC Driver][SQLServer]The statement has been terminated.

2004-02-25 09:57:36,593(2140) [main] ERROR net.sf.hibernate.util.JDBCExceptionReporter  - could not insert: [com.dealeasy.ems.monitor.table.DePurchaseOrderLineModel]

java.sql.SQLException: [Microsoft][SQLServer JDBC Driver][SQLServer]Cannot insert the value NULL into column 'PURC_ORDER_ID', table 'ems_monitor.dbo.de_purchase_order_line'; column does not allow nulls. INSERT fails.

   at com.microsoft.jdbc.base.BaseExceptions.createException(Unknown Source)
.....


I am frighting with this problem more than 3 days. Can somebody help me to solve it?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 25, 2004 1:41 am 
Regular
Regular

Joined: Wed Dec 03, 2003 9:41 pm
Posts: 87
I had found my mistake. I don't call method like child.setParent. But I still have a question.
In first sample:
Code:
http://www.hibernate.org/155.html

It uses HashSet to store children. In this sample, one child, it is ok. But I find if I have more than one child, hibernate will only save one child. I think the problem is new Child() are all same by default to store in HashSet. Because new Child() has not a PK and java code generated by hibernate tool using PK:id to spearte instance. What is a good way to store children? Using List or anything else instead of HashSet or modify default equals method generated by tool?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 25, 2004 8:30 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
http://www.hibernate.org/109.html

_________________
Emmanuel


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