-->
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.  [ 13 posts ] 
Author Message
 Post subject: List Collection question wrt to null/empty children
PostPosted: Mon Mar 01, 2004 8:33 pm 
Beginner
Beginner

Joined: Thu Nov 06, 2003 10:04 pm
Posts: 22
I have come across this problem of not being able to load/find a Parent from the database that has basically a 'null/empty' Child collection.

My mapping from Parent->Child is a non-lazy uni-directional List collection ( I have read in the doco that Hibernate does not support bi-directional Lists ), with cascade="all-delete-orphan" set on it.

When my Parent instance has a non-null Child collection instance in it, I can persist and load/find it back from the database alright.

But if I have a Parent with a null/empty Child collection, then everything gets saved properly. But when I try to retrieve that Parent using either load or find, Hibernate throws an exception saying "you cannot dereference a collection with cascade="all-delete-orphan".

I have not been able to figure out any other way to load that Parent with a null Child collection. And since this is supposed to be a List collection, I cannot make it a bi-directional (and I donot want to use a Set and a separate index attribute in the Child to simulate a List collection).

Can anyone throw some light on why I would be getting that exception and how can I avoid it with the restrictions I have?

Or is this how it is, that a List hibernate collection cannot be null/empty?

Thanks
Rama


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 02, 2004 12:36 am 
Regular
Regular

Joined: Mon Nov 24, 2003 6:36 pm
Posts: 105
suggestions: use the search function and read the wiki page on inverse=true if you have db constraints.

Hibernate can do lists (instead of set) if you use idbag, or your db has a field it can position elements in the list with.

Post more code/mapping ...etc
james


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 02, 2004 4:12 am 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
Collection propertys are never null, they can be empty, but not null. It should work with an empty collection.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 02, 2004 2:29 pm 
Beginner
Beginner

Joined: Thu Nov 06, 2003 10:04 pm
Posts: 22
We have tried both null collection instance and also empty collection instance. Both cases, it fails when we try to load the Parent back using either load/find.

And as I said we needed to use the List Collection and it does not support bi-directional mapping (hence inverse="true" issue does not even come up).

In any case this is the mapping/code.

Code:
<class name="Parent" table="parents">
  <key>
      <column name="parent_id", sql-type="char(36)"/>
  </key>
  <list name="children" cascade="all-delete-orphan">
       <key>
           <column name="parent_id" sql-type="char(36)"/>
       </key>
       <index column="index"/>
       <one-to-many class="Child"/>
  </list>
</class>

<class name="Child" table="children">
   <key>
       <column name="child_id" sql-type="char(36)"/>
   </key>
</class>


And doing session.save( parent ) works fine even if the "children" collection is empty or null. But doing session.load( parent ) or session.find( "from Parent" ), both throw that error, when "children" collection is either null or empty.

Any suggestions?
Thanks


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 02, 2004 7:29 pm 
Beginner
Beginner

Joined: Thu Nov 06, 2003 10:04 pm
Posts: 22
After debugging a bit more, we saw in the exception that hibernate was doing a "flush", during the process of finding/loading the Parent instance along with its children.

We modified the code to surround the find/load call with setting flush mode to 'never' and back to 'eager/auto' (whatever it was before the call), things seem to work fine. So it appears that if my Parent has a null/empty Child collection, doing a flush results in that exception. And things work fine after we disable flush for that find/load call.

Does this make sense? Any explanations?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 03, 2004 5:08 am 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
Well I don't think this is the actual mapping you use, as <key> on class level makes absolutely no sense and the parser would surely complain about that.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 03, 2004 2:26 pm 
Beginner
Beginner

Joined: Thu Nov 06, 2003 10:04 pm
Posts: 22
It was a mistake when I inserted the code. It is the <id> tag instead of the key.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 03, 2004 2:59 pm 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
Show the code you are executing between session open and close please. If you can't, try to simplify to reproduce exactly the problem.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 03, 2004 3:19 pm 
Beginner
Beginner

Joined: Thu Nov 06, 2003 10:04 pm
Posts: 22
Code:
<class name="Parent" table="parents">
  <id name="id" type="UUIDType">
      <column name="parent_id", sql-type="char(36)"/>
      <generator class="ourOwnGenerator"/>
  </id>
  <list name="children" cascade="all-delete-orphan">
       <key>
           <column name="parent_id" sql-type="char(36)"/>
       </key>
       <index column="list_index"/>
       <one-to-many class="Child"/>
  </list>
</class>

<class name="Child" table="children">
  <id name="id" type="UUIDType">
      <column name="child_id", sql-type="char(36)"/>
      <generator class="ourOwnGenerator"/>
  </id>
</class>


public Parent saveParent( Parent parent ) throws HibernateException {
     Session session = null;
     session = _sessionFactory.openSession();
     session.saveOrUpdate( parent );
     session.flush();
     return parent;
}

public Category getParent( UUID parentId ) throws HiberanteException {
     Session session = null;
     session = _sessionFactory.openSession();

     String queryString = "from Parent parent where parent.id = ?";

     return (Parent)session.load( Parent.class, parentId )
}


I create a new Parent at the client, add "no" children to it. So the Child collection is empty (it did not matter whether it was empty or null).

Persist the new Parent using saveParent(), and get the persisted Parent back at the client.

I do no changes to it at the client, just retrieve its generated UUID, and try to retrieve the Parent from the database using getParent(). Thats when this error happens. (There are no problems with the UUID generator, what I receive at the client is what is in the parent_id column in parents table).

Everything works fine if I had added a few Childs to the Parent at the beginning, save it, get it back using getParent(), modify children collection (add/remove), and save it again, and then get it back using getParent() (and I verified too that orphans are being deleted). So I know everything works fine, if the Child collection is non-null or not empty.

Thanks


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 03, 2004 3:35 pm 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
Hm, you are closing those sessions there, are you? Please try to reproduce the problem using a small example and show us that (or post to JIRA). No one can really tell without the code you are actually executing.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 03, 2004 3:48 pm 
Beginner
Beginner

Joined: Thu Nov 06, 2003 10:04 pm
Posts: 22
Code:

<class name="Parent" table="parents">
  <id name="id" type="UUIDType">
      <column name="parent_id", sql-type="char(36)"/>
      <generator class="ourOwnGenerator"/>
  </id>
  <list name="children" cascade="all-delete-orphan">
       <key>
           <column name="parent_id" sql-type="char(36)"/>
       </key>
       <index column="list_index"/>
       <one-to-many class="Child"/>
  </list>
</class>

<class name="Child" table="children">
  <id name="id" type="UUIDType">
      <column name="child_id", sql-type="char(36)"/>
      <generator class="ourOwnGenerator"/>
  </id>
</class>


public Parent saveParent( Parent parent ) throws HibernateException {

     Session session = _sessionFactory.openSession();

     session.saveOrUpdate( parent );
     session.flush();

     session.close();

     return parent;
}

public Category getParent( UUID parentId ) throws HiberanteException {

     Session session = _sessionFactory.openSession();

     String queryString = "from Parent parent where parent.id = ?";

     Parent parent = (Parent)session.load( Parent.class, parentId );
     // Remember no 'lazy' on children collection, so above will retrieve all
     // Child associated with Parent, if any exist
     session.close();

     return parent;
}

ON THE CLIENT SIDE, an example using main in some other class.
(No Session available here and all the calls to above dao methods are thru a Stateless Session Bean)

public static void main( String[] args ) {

  Parent parent = new Parent();
  // I will not add any Child. So parent.getChildren() will return an 'empty' List

  Parent savedParent = saveParent( parent );
  // Verified Parent got saved to parents, with no Child in children table 

  Parent retrievedParent = getParent( savedParent.getId() );
  // Above call generates the error "you cannot dereference a
  // collection with cascade="all-delete-orphan"

}



As I said, everything with the above code is great, if I have a non-null or non-empty children collection

Thanks


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 03, 2004 3:51 pm 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
Please show the exception stacktrace.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 03, 2004 9:47 pm 
Beginner
Beginner

Joined: Thu Nov 06, 2003 10:04 pm
Posts: 22
I had intended to put the exception stack before, but forgot. In the meantime, I have realized that the issue was with Spring's HibernateTemplate (which I am using to do the Hibernate work) and its flush mode setting.

For some reason, HibernateTemplate seems to be invoking flush() even for a find call, and even though its flush mode is set to AUTO. Currently I am trying to figure out how to integrate HibernateInterceptor in my dao.

But currently, even though I have integrated the interceptor, the error still comes up, as flush is still being done. I am not exactly sure which attribute in the spring application context file bean definition controls this flushing behavior.

In the meantime, if anyone can give me info on how to set the flush behavior using the interceptor and spring, I would appreciate it.

Thanks


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