-->
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.  [ 4 posts ] 
Author Message
 Post subject: Problem in a one-to-many relationship
PostPosted: Tue Aug 23, 2005 6:24 am 
Hi folks,

I have a problem with a one-to-many relationship :

I have 2 classes Transactions and TransationLines
Code:
  public class TransactionInfo
   {
      public TransactionInfo()
      {
         Lines = new ArrayList();
      }

      public Int32 Id;
      public string CommentTop;
      public string CommentBottom;
      ...

      [XmlArray("Lines"), XmlArrayItem(typeof(TransactionLineInfo))]
      public IList Lines;
   }
   
   public class TransactionLineInfo
   {
      public TransactionLineInfo()
      {
      }

      public Int32 Id;
      public int Quantite;
      public string Description;
      ...
   }


mapped as :

Code:

  <class
   name="MyCompany.Modules.ModA.Models.Transactions.TransactionInfo, MyCompany.Modules.ModA.Models"
   table="Transactions_Transactions">
   
    <id name="Id" column="TransactionId" type="Int32" unsaved-value="0">
      <generator class="native" />
    </id>
   
    <property name="CommentTop" type="String" />
    <property name="CommentBottom" type="String" />
   ....
   
    <bag name="Lines" table="TransactionLignes" cascade="all-delete-orphan" lazy="false" inverse="true">
      <key column="TransactionId" />
      <one-to-many class="MyCompany.Modules.ModA.Models.Transactions.TransactionLineInfo, MyCompany.Modules.ModA.Models" />
    </bag>

  </class>
 
  <class
   name="MyCompany.Modules.ModA.Models.Transactions.TransactionLineInfo, MyCompany.Modules.ModA.Models"
   table="Transactions_TransactionLignes">
   
    <id name="Id" column="TransactionLigneId" type="Int32" unsaved-value="0">
      <generator class="native" />
    </id>
   
    <property name="Quantite" type="Int32" />
    <property name="Description" type="String" />
    ...
  <!-- Note: the 'transactionId' column that is used to make the link between a Transaction and its lines is not mapped -->
  </class>


Let's take an example :

Code:
Transaction trx = new Transaction();
TransactionLine l1 = new TransactionLine();
trx.CommentTop = "....";
l1.Description = ".....";
trx.Lines.Add(l1);
session.Save(trx);


The problem is that 'trx' is saved, 'l1' is saved but the link between trx and l1 is not assigned in the database (ie table TransactionLine.TransactionId = null)
I checked the generated sql and saw that at no time nhibernate does the association between trx and l1.
Here is the sequence in the log:
- INSERT INTO Transaction ... trx's properties ....
- Get the new Trx'Id ("Natively generated identity...")
- Detects the cascades
- INSERT INTO TransactionLines ... l1's properties BUT NO REFERENCE TO TRANSACTIONID !! ....

I checked with and without "inverse=true", giving the same result.

Someone faced the same problem ?

Thx in advance and have a nice day.


Top
  
 
 Post subject:
PostPosted: Tue Aug 23, 2005 8:00 am 
Regular
Regular

Joined: Mon Jul 18, 2005 4:10 am
Posts: 92
Location: Poland
Hi,
when using inverse="true" you need to map many-to-one relation in your child , for example <many-to-one name="parent" column="parent_id" not-null="true"/> (transactionId in your case) Also remeber that the "bags" are not recommended without inverse="true" (use "Set" if you decide to use inverse="false" - in other case the whole collection will be deleted and recreated with any data change)

Because it is not so obvious subject I strongly recommend "deep" reading chapter 8 of the docs http://nhibernate.sourceforge.net/h2.0.3-docs/reference/html/parent-child.html

_________________
michal


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 24, 2005 8:18 am 
Thx for ur answer Michal :)

I set up the many-to-one thing, but came another problem.
To understand, let me explain you the architecture of the project :

- a UI that calls the webservices (no link with dal, model or bll)
- a webservice (CRUD methods for TransactionInfo objects)
- a BLL
- a DAL (that use NHibernate)
- a Model class that stores all entities class (ie TransactionInfo, TransactionLineInfo, etc.)

I set a many-to-one link, it means that I have to add a "Parent" property to TransactionLineInfo.

Since TransactionInfo and TransactionLineInfo are exposed by the webservice, I need to set a [XmlIgnore()] on the "Parent" property to avoid a loop of serialization/deserialization on these entities.

In the DAL, before saving the object, I ensure links are correct by
relinking (trx.line.Parent = trx)

It works very well (add, update), until the moment I delete a TransactionLine from a Transaction :
nhibernate doesn't generate a DELETE command (that I don't understand since I precised cascade="all-delete-orphan".
Here is the sequence:
1. UI gets Transaction (thus the TransactionLines too) by the webservice
2. UI removes a line from Transaction.Lines
3. UI sends the Transaction back to the webservice
4. -- go through the layers --
5. (DAL) ensure transaction <-> transactionLine links
6. (DAL) session.SaveOrUpdate(transaction)

-> the line removed is still present in the database, and still linked to the transaction (transactionLine.transactionId != null)

What am I doing wrong ?


Top
  
 
 Post subject:
PostPosted: Thu Aug 25, 2005 5:24 am 
Regular
Regular

Joined: Mon Jul 18, 2005 4:10 am
Posts: 92
Location: Poland
Hi,
I don't know it so deeply but as far I know the collections (IList in your case) MUST be a "proxy" to let the nhibernate know that you are deleting sth from them. So in your case you are loosing this information durign XML serialization/deserialization between UI and WS. Please someone correct me if I am wrong.
But if it is true, you should consider redesigning this part - for example WS method "deleteLineFromtrans(trans_id,line_id)" , re-read trans (or Lock it with Session) on the server, so the collection will be a proxy again and then - delete the line here. Then use session.flush() (not SaveOrUpdate) to commit the deletion.
Good luck.

_________________
michal


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