-->
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: Serialized collection problems
PostPosted: Tue Sep 21, 2004 4:53 am 
Newbie

Joined: Fri Sep 17, 2004 2:34 am
Posts: 3
Hello, I am using hibernate in a (stateless) webservice scenario with a fat swing client.

I have no problem querying for information and present this. But when I change something and saves it by sending the graph back, I get weird SQL updates on my collection tables.

Scenario:

1. Query and get full object graph.
2. (DMO->DTO) Convert graph to something SOAP understand, such as array instead of set.
3. Send through SOAP
4. Client: Receive from SOAP and convert it back to something more workable (DTO->DMO)
5. Client: User does something in UI. Work with graph, add, remove and edit objects and values.
6. Client: Save the graph, convert back to DTO, send through SOAP.
7. Server: Build DMO from DTO
8. Create new session, and call saveOrUpdate on the DMO.
9. Everything first seems to works nice but the last update hibernate generates is weird. It tries to set fk to null in a connection table.

I suspect it has to do with the collection object, since the collection objects are not the original object that hibernate populated in the query.

Before I send logs, and mappings I just want to check if it is possible to do what I described in the scenario, eg. Detach, transform, serialize, deserialize, transform, reattach collections. I have also tried the following which gives me the same problem:

1. Session 1: Get object graph with a collection
2. Close session 1
3. Copy object graph (with a simple copy constructor)
4. Session 2: call saveOrUpdate on the copy
5. Fails by trying to update a fk to null.

Any clues?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 23, 2004 6:37 am 
Newbie

Joined: Fri Sep 17, 2004 2:34 am
Posts: 3
I was really hoping someone had any clues, I have done a minimal example that will replicate the problem I have.

First of all I am using Hibernate 3.0-alpha.


The example has a category and an item class mapped as:

Code:
<hibernate-mapping>

    <class name="Test.Category" table="Category">

        <id name="id" type="integer" unsaved-value="0" >
            <generator class="identity"/>
        </id>

      <property name="name" not-null="true"/>

      <set name="Items" cascade="all" lazy="false">
         <key column="catId"/>
         <one-to-many class="Test.Item"/>
      </set>

    </class>

</hibernate-mapping>


Code:
<hibernate-mapping>

    <class name="Test.Item" table="Item">

        <id name="id" type="integer" unsaved-value="0" >
            <generator class="identity"/>
        </id>

      <property name="name" not-null="true"/>

      <many-to-one name="cat" class="Test.Category" column="catId" not-null="true" cascade="none"/>

    </class>

</hibernate-mapping>



The following classes implement Category and Item:



Code:
public class Category implements Serializable {

   int id;
   String name;
   Set items;

   public Category() {
      this.id = 0;
      this.name = "new";
      items = new HashSet();
   }

   public Category(int id,String name) {
      this.id = id;
      this.name = name;
      items = new HashSet();
   }

   /Removed simple getters/setters   

   public static Category newInstance(Category o) {

      Category c = new Category(o.getId(),o.getName());

      for (Iterator it = o.getItems().iterator(); it.hasNext();) {
         Item item = (Item) it.next();
         c.items.add(Item.newInstance(c,item));
      }

      return c;
   }
}



Code:
public class Item {

   private int id;
   private String name;
   Category cat;

   public Item() {
      this.id = 0;
      this.name = "new";
      this.cat = null;
   }

   public Item(int id, String name, Category cat) {
      this.id = id;
      this.name = name;
      this.cat = cat;
   }

   /Removed simple getters/setters   

   public static Item newInstance(Category c,Item o) {
      Item item = new Item(o.getId(),o.getName(),o.getCat());
      return item;
   }
}



If I execute the following:

    Session 1: Get a Category object
    Close session 1
    Copy object graph (to simulate the behavior I described above with my webservice scenario)
    Session 2: call saveOrUpdate on the copy

Code:
Code:
Session session = PiM.Server.PiMServer.getSessions().openSession();
Transaction tx=null;
try {
   tx = session.beginTransaction();
   Category cat = (Category) session.get(Category.class,new Integer(1));
   tx.commit();
   session.close();

   Category clone = Category.newInstance(cat);

   tx=null;
   session = PiM.Server.PiMServer.getSessions().openSession();
   tx = session.beginTransaction();
   session.saveOrUpdate(clone);
   tx.commit();

} catch (HibernateException he){
   if (tx!=null)
      tx.rollback();
   throw he;
} finally {
   session.close();
}




I get the following log:

Code:
Hibernate: select category0_.id as id0_, category0_.name as name4_0_ from Category category0_ where category0_.id=?
Hibernate: select items0_.catId as catId__, items0_.id as id__, items0_.id as id0_, items0_.name as name5_0_, items0_.catId as catId5_0_ from Item items0_ where items0_.catId=?
Hibernate: update Category set name=? where id=?
Hibernate: update Item set name=?, catId=? where id=?
Hibernate: update Item set name=?, catId=? where id=?
Hibernate: update Item set name=?, catId=? where id=?
Hibernate: update Item set name=?, catId=? where id=?
Hibernate: update Item set name=?, catId=? where id=?
Hibernate: update Item set catId=null where catId=?
2004-sep-23 12:29:02 org.hibernate.util.JDBCExceptionReporter logExceptions
VARNING: SQL Error: -407, SQLState: 23502
2004-sep-23 12:29:02 org.hibernate.util.JDBCExceptionReporter logExceptions
ALLVARLIG: [IBM][CLI Driver][DB2/NT] SQL0407N  Assignment of a NULL value to a NOT NULL column "TBSPACEID=2, TABLEID=5, COLNO=2" is not allowed.  SQLSTATE=23502


Any one have any clue why Hibernate will do the update:

update Item set catId=null where catId=?

Which is clearly wrong.

Cheers Okku


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 23, 2004 7:57 am 
Expert
Expert

Joined: Thu Jan 29, 2004 2:31 am
Posts: 362
Location: Switzerland, Bern
Quote:
I suspect it has to do with the collection object, since the collection objects are not the original object that hibernate populated in the query.

AFAIK that's the point. Removing the cascade attribute and call upate for your items by hand should work.
An other solution would be to retrive the data again and do a synchronize between the DTOs and the DMOs. Use the second level cache to minimize the number DB roundtrips.

HTH
Ernst


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 24, 2004 9:54 am 
Newbie

Joined: Fri Sep 17, 2004 2:34 am
Posts: 3
I have got it working by downloaded version 2.1.6 and calling saveOrUpdateCopy instead of saveOrUpdate and it works, great!

But when I searched the forum I got the feeling that saveOrUpdateCopy is bad and has bugs. Gavin mentions it in this thread:

http://forum.hibernate.org/viewtopic.ph ... updatecopy

Am I on the right track by using saveOrUpdateCopy? Or should try to avoid it?

And by the way where is saveOrUpdateCopy in 3.0?

/Okku


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.