• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • paul wheaton
  • Paul Clapham
  • Ron McLeod
Sheriffs:
  • Jeanne Boyarsky
  • Liutauras Vilda
Saloon Keepers:
  • Tim Holloway
  • Carey Brown
  • Roland Mueller
  • Piet Souris
Bartenders:

Hibernate .hbm.xml - Referential Integrity constraint

 
Ranch Hand
Posts: 45
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi All,
I have a table Invoice. Then I have a table sales. The invoice table has Primary Key as Invoice Number. Sales table holds all the items or sales for a particular invoice.
The invoice Number field of the sales table has a fkey relation with the invoice number of the Invoice table.
I have made the Invoice number of the Invoice table be auto incremented.
The problem I am facing is , using Hibernate, I am trying to create a record in the invoice table use that invoice number for creating records in the sales table. My invoice.hbm.xml looks as follows

<hibernate-mapping package="com.postsales.domain.model">
<class name="Invoice" table="invoice">
<id name="invoiceNumber" column="InvoiceNumber">
<generator class="native"></generator>
</id>
<property name="invoiceDate" column="InvoiceDate" not-null="true" />
<property name="invoiceTotal" column="InvoiceTotal" not-null="true" />
<property name="customerName" column="CustName" not-null="true" />
<list name="itemList" cascade="all">
<key column="InvoiceNumber" />
<index column="Sales_Number" />
<one-to-many class="Sales" />
</list>
</class>
<class name="Sales" table="salesdetails">
<id name="salesNumber" column="Sales_Number" >
<generator class="native"></generator>
</id>
<property name="prodCode" column="Prod_Code" not-null="true" />
<property name="salesDate" column="Sales_Date" not-null="true" />
<property name="storeID" column="From_Store" not-null="true" />
<property name="invoiceNumber" column="InvoiceNumber"
lazy="true"/>

<property name="empID" column="Empl_ID" not-null="true" />
<property name="desc" column="Description" not-null="true"></property>
<property name="price" column="Price" not-null="true"></property>
<property name="quantity" column="Quantity" not-null="true"></property>
</class>
</hibernate-mapping>



Somehow the application is trying to insert new records first into the sales table then into the Invoice table. Because of this its getting the invoice number field as null.
please suggest me what chould I do so that either the order of creation of tables is reverse or a workaround to created the sales record and then update them with the invoice number.

thanks in advance,
Kavitha.
 
ranger
Posts: 17347
11
Mac IntelliJ IDE Spring
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Please use the Code tags for your posts, without the indentation xml and code is really hard to read and figure where one object stops and another begins. There are buttons a the top of posting that have all the tags you could possibly want. Including the Code tags.

Thanks

Mark
 
Mark Spritzler
ranger
Posts: 17347
11
Mac IntelliJ IDE Spring
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well in your Sales object you have

<property name="invoiceNumber" column="InvoiceNumber"
lazy="true"/>

But Hibernate does not know that this is coming from the Invoice object, so unless it gets set by you then it will set it to null.

If you want the association to be bi-directional, then map the Invoice object as a ManyToOne in the Sales object mapping, and make sure you set it to inverse="true".

Mark
 
Kavita Shivani
Ranch Hand
Posts: 45
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ok I will try that one.
But one question, it still tries to create records in Sales table first and still wont find the invoicenumber, how would that be handled? Because during my trial and error, all through yesterday I tried that as well, and dont think it worked. But may be trying to get it working repeatedly I must have missed out something, I will give it a shot again today.
thanks,
Kavitha.
 
Kavita Shivani
Ranch Hand
Posts: 45
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Sorry for not using the code tag, shall do that from now.
 
Kavita Shivani
Ranch Hand
Posts: 45
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Mark,
Its still not working. Following are the changes I made.

Invoice.hbm.xml



Sales.hbm.xml


Note, I tried different ways of creating the many-to-one relation, like giving the column name as well etc. the inverse tag was only applicable for the one-to-many side of the relation, so I have put it on the Invoice hbm.

Exception
org.hibernate.AssertionFailure: null id in com.postsales.domain.model.Sales entry (don't flush the Session after an exception occurs)
at org.hibernate.event.def.DefaultFlushEntityEventListener.checkId(DefaultFlushEntityEventListener.java:55)
at org.hibernate.event.def.DefaultFlushEntityEventListener.getValues(DefaultFlushEntityEventListener.java:157)
at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:113)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:196)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:76)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)


Right now as a workaround, I am treating these as two separate tables, removed the relationship mapping from the hbm, I have the transaction management at the service level so I believed that it will handle things, of making it as a single transaction, and so updating them separately as two tables just as we do in database just go and insert one record, and use that id and update the table with the foreign key.

In my Dao, I have the following:


I know thats a bit crude way of doing it, but its working for me. Do comment on my xml if you think any changes would help me.


thank you,
Kavitha.
reply
    Bookmark Topic Watch Topic
  • New Topic