-->
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.  [ 8 posts ] 
Author Message
 Post subject: collection of strings problem
PostPosted: Tue Dec 20, 2005 9:13 pm 
Newbie

Joined: Wed Nov 16, 2005 2:40 pm
Posts: 19
Location: Palo Alto, CA
Hi

I am completely befuddled by this problem: I have a list of strings in my DOM that I want to persist. The other properties get saved, but the list is silently dropped.

My schema looks like this:
Code:

  <class name="CVAS.Primitives.Question, Primitives" table="Questions">
    <id name="ID">
      <generator class="native" />
    </id>
    <property name="Template" />
    <property name="Prompt" not-null="true" />
    <property name="Sequence" />
    <many-to-one name="QuestionSet" class="CVAS.Primitives.QuestionSet, Primitives" column="QuestionSet" />
  </class>

  <joined-subclass name="CVAS.Primitives.CategoricalQuestion, Primitives" extends="CVAS.Primitives.Question, Primitives" table="CategoricalQuestions">
    <key column="QuestionID" />
    <list name="OptionsList" table="CategoricalOptions">
      <key column="QuestionID" />
      <index column="QuestionSequence" />
      <element column="Value" type="string" not-null="true" />
    </list>
  </joined-subclass>



The relevant log looks like this
Code:
2005-12-20 13:53:59,824 [5472] DEBUG NHibernate.Impl.SessionImpl [(null)] <(null)> - saving [CVAS.Primitives.CategoricalQuestion#<null>]
2005-12-20 13:53:59,824 [5472] DEBUG NHibernate.Impl.SessionImpl [(null)] <(null)> - executing insertions
2005-12-20 13:53:59,824 [5472] DEBUG NHibernate.Impl.WrapVisitor [(null)] <(null)> - Wrapped collection in role: CVAS.Primitives.CategoricalQuestion.OptionsList
2005-12-20 13:53:59,824 [5472] DEBUG NHibernate.Persister.NormalizedEntityPersister [(null)] <(null)> - Inserting entity: CVAS.Primitives.CategoricalQuestion (native id)
2005-12-20 13:53:59,824 [5472] DEBUG NHibernate.Impl.BatcherImpl [(null)] <(null)> - Opened new IDbCommand, open IDbCommands :1
2005-12-20 13:53:59,824 [5472] DEBUG NHibernate.Impl.BatcherImpl [(null)] <(null)> - Building an IDbCommand object for the SqlString: INSERT INTO dbo.Questions (QuestionSet, Prompt, Template, Sequence) VALUES (:QuestionSet, :Prompt, :Template, :Sequence); select SCOPE_IDENTITY()
2005-12-20 13:53:59,824 [5472] DEBUG NHibernate.Type.Int64Type [(null)] <(null)> - binding '1' to parameter: 0
2005-12-20 13:53:59,824 [5472] DEBUG NHibernate.Type.StringType [(null)] <(null)> - binding 'True or false?' to parameter: 1
2005-12-20 13:53:59,824 [5472] DEBUG NHibernate.Type.StringType [(null)] <(null)> - binding 'CVAS.WebUI.Question_MultipleChoice' to parameter: 2
2005-12-20 13:53:59,824 [5472] DEBUG NHibernate.Type.Int32Type [(null)] <(null)> - binding '1' to parameter: 3
2005-12-20 13:53:59,824 [5472] DEBUG NHibernate.SQL [(null)] <(null)> - INSERT INTO dbo.Questions (QuestionSet, Prompt, Template, Sequence) VALUES (@p0, @p1, @p2, @p3); select SCOPE_IDENTITY()
2005-12-20 13:53:59,834 [5472] DEBUG NHibernate.Impl.BatcherImpl [(null)] <(null)> - Opened Reader, open Readers :1
2005-12-20 13:53:59,834 [5472] DEBUG NHibernate.Persister.AbstractEntityPersister [(null)] <(null)> - Natively generated identity: 1
2005-12-20 13:53:59,834 [5472] DEBUG NHibernate.Driver.NHybridDataReader [(null)] <(null)> - running NHybridDataReader.Dispose()
2005-12-20 13:53:59,834 [5472] DEBUG NHibernate.Impl.BatcherImpl [(null)] <(null)> - Closed Reader, open Readers :0


What happens after the collection is wrapped? Nothing seems to get saved in the database. I tried adding a cascade attribute on the list, but that didn't help.

What am I missing?

Gene


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 21, 2005 1:05 pm 
Senior
Senior

Joined: Wed Jun 15, 2005 4:17 am
Posts: 156
try to add a cascade attribute to your list mapping.

HTH,
Radu


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 21, 2005 2:14 pm 
Newbie

Joined: Wed Nov 16, 2005 2:40 pm
Posts: 19
Location: Palo Alto, CA
radu wrote:
try to add a cascade attribute to your list mapping.

HTH,
Radu


I had tried it with the cascade attribute, but the behavior is the same. As far as I can tell by stepping through the code, in Cascades.Cascade method, it only cascades a collection of entity, objet, or component types, of which string is neither. The relevant code snippet is:

Code:
   if( ( ( IAssociationType ) type ).ForeignKeyType.CascadeNow( cascadeTo ) )
   {
      if( type.IsEntityType || type.IsObjectType )
      {
         action.Cascade( session, child, anything );
      }
      else if( type.IsPersistentCollectionType )
      {
         CascadePoint cascadeVia;
         if( cascadeTo == CascadePoint.CascadeAfterInsertBeforeDelete )
         {
            cascadeVia = CascadePoint.CascadeAfterInsertBeforeDeleteViaCollection;
         }
         else
         {
            cascadeVia = cascadeTo;
         }
         PersistentCollectionType pctype = ( PersistentCollectionType ) type;
         ICollectionPersister persister = session.Factory.GetCollectionPersister( pctype.Role );
         IType elemType = persister.ElementType;
         // cascade to current collection elements
         if ( elemType.IsEntityType || elemType.IsObjectType || elemType.IsComponentType )
         {
            CascadeCollection( action, style, pctype, elemType, child, cascadeVia, session, anything );
         }
      }
   }


So the CascadeCollection method is not called on a collection of strings. Now this is not surprising, since it's now clear how it would know where to persist the string collection, but what I don't understand is where in the code such a collection would be stored.

Gene


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 23, 2005 12:50 pm 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
Did you call Flush? Please show the code you use to save the object.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 23, 2005 3:37 pm 
Newbie

Joined: Wed Nov 16, 2005 2:40 pm
Posts: 19
Location: Palo Alto, CA
sergey wrote:
Did you call Flush? Please show the code you use to save the object.


Ahh, that solved both problems I had with collections. Thank you!

For the future (and for the full-text index of this forum):
You MUST flush the session explicitly to cause collection contents that do not have bi-directional links to be saved. This applies both to collections of immutables (long, string, int, etc.) and to collections of objects. How could we make this more explicit in the documentation?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 23, 2005 4:04 pm 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
You should call flush for ANY changes at all to be saved (there are a few exceptions which often confuse the users though :-(). And, it's better to use transaction API (ISession.BeginTransaction/Commit) than explicit flushes.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 23, 2005 4:38 pm 
Newbie

Joined: Wed Nov 16, 2005 2:40 pm
Posts: 19
Location: Palo Alto, CA
sergey wrote:
You should call flush for ANY changes at all to be saved (there are a few exceptions which often confuse the users though :-(). And, it's better to use transaction API (ISession.BeginTransaction/Commit) than explicit flushes.


This might be somewhat off-topic, but what are the reasons for using BeginTransaction & Commit rather than a flush at the end of the session?

Also, was there a rationale for not including Flush in the Close() method?

Gene


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 23, 2005 5:20 pm 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
Close can (and should) also be used when rolling back a transaction, that's why Flush is not included in Close.

You should use transactions instead of just Flush because a) every interaction with the database should happen inside a transaction and b) NHibernate assumes sometimes that you can roll back in case of errors and you can't roll back without a transaction.


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