-->
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: Updating a composite id
PostPosted: Sun Jul 22, 2007 6:12 am 
Beginner
Beginner

Joined: Thu May 10, 2007 4:20 am
Posts: 27
Hello,

I have a table in a database, which has 3 columns, all being part of its primary key.
I mapped this table, using a composite id, like this:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="path.to.class.Class1" table="table1">
<composite-id>
<key-property name="id1" column="id1"/>
<key-many-to-one name="id2" class="path.to.class.Class2" column="id2" lazy="false"/>
<key-property name="id3" column="id3"/>
</composite-id>
</class>
</hibernate-mapping>


But when I update in code one of these fields, no update is issued to the database.

Here's the code I'm using:

Transaction tr;

tr = HibernateUtil.getSessionFactory().getCurrentSession().beginTransaction();
List objects = HibernateUtil.getSessionFactory().getCurrentSession().createQuery("from Class1 where hierarchyId=15").list();
Class1 obj = (Class1) objects.get(0);
obj.setId3(new Integer(18));
HibernateUtil.getSessionFactory().getCurrentSession().flush();
tr.commit();

What am I doing wrong?

Thanks,
Vitaliy


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jul 22, 2007 1:27 pm 
Beginner
Beginner

Joined: Thu May 10, 2007 4:20 am
Posts: 27
Sorry, I've got a typo there -

the code should be:

Transaction tr;

tr = HibernateUtil.getSessionFactory().getCurrentSession().beginTransaction();
List objects = HibernateUtil.getSessionFactory().getCurrentSession().createQuery("from Class1 where id3=15").list();
Class1 obj = (Class1) objects.get(0);
obj.setId3(new Integer(18));
HibernateUtil.getSessionFactory().getCurrentSession().flush();
tr.commit();

I'll really appreciate any advice,
Vitaliy


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 23, 2007 1:47 am 
Newbie

Joined: Fri Jun 29, 2007 9:03 am
Posts: 12
Hi

instead of
HibernateUtil.getSessionFactory().getCurrentSession().flush();

try doing

HibernateUtil.getSessionFactory().getCurrentSession().save(obj);

because flush() will detach the object and move into transient state. so when u do commit () nothing is there with session to commit()

If this works pls rate the post ..


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 23, 2007 3:47 am 
Beginner
Beginner

Joined: Thu May 10, 2007 4:20 am
Posts: 27
Thanks for your reply,

But saving the object has no effect.

Anyway, as far as I can understand Hibernates' documentation, save should be used in order to insert a new object, rather than updating an existing one.
If a persistent object is updated in the code, the change should be automatically reflected in the database, upon committing or flushing the session..

So why won't this work like this with composite ids??

Thanks,
Vitaliy


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 23, 2007 5:33 am 
Newbie

Joined: Fri Jun 29, 2007 9:03 am
Posts: 12
Hi

wht u r saying is correct . I just went through a link -
http://neeraj.name/2005/07/02/hibernate-sessionclose-does-_not_-call-sessionflush

it says with transaction dont use flush(), only with session.close() u shld use .. go through it, will be more clear


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 23, 2007 5:53 am 
Beginner
Beginner

Joined: Thu May 10, 2007 4:20 am
Posts: 27
Thanks for your effort,

but even if I comment out the flush statement,
i.e. my code looks like this now:

Transaction tr;

tr = HibernateUtil.getSessionFactory().getCurrentSession().beginTransaction();
List objects = HibernateUtil.getSessionFactory().getCurrentSession().createQuery("from Class1 where id3=15").list();
Class1 obj = (Class1) objects.get(0);
obj.setId3(new Integer(18));
//HibernateUtil.getSessionFactory().getCurrentSession().flush();
tr.commit();

It has no effect!
Actually, I added the flush statement only because the original code with just the commit didn't work..

Also, this behavior is only due to the composite id.
If I move the id3 property outside of the composite id definition in the mapping file, it gets updated perfectly!

Any ideas??

Thanks,
Vitaliy


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 23, 2007 5:55 am 
Beginner
Beginner

Joined: Thu May 10, 2007 4:20 am
Posts: 27
That is - this issue looks unrelated to transactions at all..


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 23, 2007 6:03 am 
Regular
Regular

Joined: Wed Jun 20, 2007 1:53 am
Posts: 75
Hi,

Try to use below code before commit the transaction.

HibernateUtil.getSessionFactory().getCurrentSession().update(obj);

- Shanmugam


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 23, 2007 6:22 am 
Beginner
Beginner

Joined: Thu May 10, 2007 4:20 am
Posts: 27
Thank you for your reply Shanmugam,

but that had no effect as well.

If I understand the documentation correctly, update should be used on detached objects, rather than on persistent, like this one.

and again, if I move the property outside of composite id - all works fine.

Thanks,
Vitaliy


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 23, 2007 6:42 am 
Newbie

Joined: Fri Jun 29, 2007 9:03 am
Posts: 12
It not possbile to update the object or row in DB if u are updating the primary key or composite key ..Every time a new composite key is there Hibernate try to do an insert .
to update a record with the composite key been changed . first delete a record and then do an insert .. A good discussion on this is given in this forum itself

http://forum.hibernate.org/viewtopic.php?t=977568&highlight=


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 23, 2007 7:32 am 
Beginner
Beginner

Joined: Thu May 10, 2007 4:20 am
Posts: 27
Thanks!

This looks logical, and it works!!
But only if I add a session.flush between the delete and insert!

my code now is:

Transaction tr;

tr = HibernateUtil.getSessionFactory().getCurrentSession().beginTransaction();
List objects = HibernateUtil.getSessionFactory().getCurrentSession().createQuery("from Class1 where id3=15").list();
Class1 obj = (Class1) objects.get(0);
HibernateUtil.getSessionFactory().getCurrentSession().delete(obj);
//HibernateUtil.getSessionFactory().getCurrentSession().flush();
obj.setId3(new Integer(18));
HibernateUtil.getSessionFactory().getCurrentSession().save(obj);
tr.commit();

It throws the following exception:

org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1

If I remove the comment at session.flush, it works. Why is it needed?

It also issues a delete and an insert statement to the db.

Actually I would have prefered that behind the sceens, hibernate would have merged the 2 delete / insert statements into a single update statement - much more efficient..

Thanks,
Vitaliy


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 24, 2007 3:51 am 
Beginner
Beginner

Joined: Thu May 10, 2007 4:20 am
Posts: 27
Anybody has an idea why must I flush?

Thnaks,
Vitaliy


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 20, 2008 4:04 am 
Regular
Regular

Joined: Wed Jun 20, 2007 1:53 am
Posts: 75
flush will sync object changes in db. Firing a sql query will happen at the time of flush. Save or update functions are just to say the operation. commit will do the actual commit in DB.

so order should be,

session.save(obj);
session.flush();
transation.commit();


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.