-->
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.  [ 12 posts ] 
Author Message
 Post subject: Hibernate query
PostPosted: Mon Apr 02, 2007 5:10 am 
Beginner
Beginner

Joined: Mon Mar 14, 2005 9:07 am
Posts: 27
Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp

Hibernate version:3.0.5

[b]Mapping documents:
Code:
<?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 package="org.hibernate.hello">
   <class name="Message" table="MESSAGES" >
      <id name="id" column="MESSAGE_ID">
         <generator class="native" />
      </id>
      <property name="text" column="MESSAGE_TEXT"/>
      
      <property name="description" column="MESSAGE_DESCRIPTION"/>
   </class>
</hibernate-mapping>


[b] I have a small query. What I am trying to do is -

1) open a new session s1
2) create a object of Message class and save it using s1 and than committing it to make sure db is updated
3) open another session s2
4) make changes in the object saved through s1 session and save it in s2 session
5) my query is that when I use s2.save(messageObject) then a new record is inserted in the db although the object already has an id associated with it.


Code:
package org.hibernate.hello;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.auction.HibernateUtil;

public class HelloManager {
   Message message;

   /**
    * @param args
    */
   public static void main(String[] args) throws Exception {
      System.out.println("Saving");
      final HelloManager helloManager = new HelloManager();
      Session s1 = HibernateUtil.currentSession();
      Transaction tx = null;
      try {
         tx = s1.beginTransaction();

         helloManager.message = new Message();
         helloManager.message.setText("Hello World");
         helloManager.message.setDescription("Description");

         s1.save(helloManager.message);

         tx.commit();
      } catch (Exception e) {
         if (tx != null)
            tx.rollback();
         throw e;
      } finally {
         HibernateUtil.closeSession();
      }

      System.out.println("id=" + helloManager.message.getId());
      helloManager.message.setDescription("New Descdription1");
      
      Session s2 = HibernateUtil.currentSession();
      tx = null;
      try {
         tx = s2.beginTransaction();

         helloManager.message.setText("New Hello World2");
         helloManager.message.setDescription("New Description2");

         s2.save(helloManager.message);

         tx.commit();
      } catch (Exception e) {
         if (tx != null)
            tx.rollback();
         throw e;
      } finally {
         HibernateUtil.closeSession();
      }      
   }

}


Thanks in advance,
Ashish Abrol


Top
 Profile  
 
 Post subject: check it
PostPosted: Mon Apr 02, 2007 6:08 am 
Beginner
Beginner

Joined: Thu Feb 01, 2007 3:08 am
Posts: 20
.... use update or saveorupdate instead of s2.save
Use the below one....


Session s1 = HibernateUtil.currentSession();
Transaction tx = null;
try {
tx = s1.beginTransaction();

helloManager.message = new Message();
helloManager.message.setText("Hello World");
helloManager.message.setDescription("Description");

helloManager.message=(helloManager.message) s1.save(helloManager.message);

tx.commit();
} catch (Exception e) {
if (tx != null)
tx.rollback();
throw e;
} finally {
HibernateUtil.closeSession();
}

System.out.println("id=" + helloManager.message.getId());
helloManager.message.setDescription("New Descdription1");

Session s2 = HibernateUtil.currentSession();
tx = null;
try {
tx = s2.beginTransaction();

helloManager.message.setText("New Hello World2");
helloManager.message.setDescription("New Description2");

s2.save(helloManager.message);

tx.commit();
} catch (Exception e) {
if (tx != null)
tx.rollback();
throw e;
} finally {
HibernateUtil.closeSession();
}
}


Regards
Gokul

PS : please don't forget to give credits below if you found this answer useful :)


Last edited by gokulnair on Mon Apr 02, 2007 6:24 am, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 02, 2007 6:18 am 
Beginner
Beginner

Joined: Mon Mar 14, 2005 9:07 am
Posts: 27
Thanks for the prompt reply.

But I still donot understand. When u say that
"In your case,in session 2 u are saving an object whose id value is null ."

However after saving the object in session s1 when I checked the id of the saved object by using System.out.println("id=" + helloManager.message.getId()); it printed me the id as 1 and NOT NULL.

Please advice.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 02, 2007 6:30 am 
Newbie

Joined: Thu Feb 22, 2007 9:49 am
Posts: 9
It seems the second Session does not know that your object has been persisted already, so it creates a new entry in the DB. Use:

Code:
s2.saveOrUpdate(helloManager.message);


for the second save instead.

As for the reason why, I'm not entirely sure, is it possible your Message.getId() method is using the Session's getIdentifier() method? If so when the first Session is closed, its cache of referenced instances containing the id of the particular Message instance is closed with it, and the new Session has no knowledge of the source of the instance.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 02, 2007 6:36 am 
Beginner
Beginner

Joined: Mon Mar 14, 2005 9:07 am
Posts: 27
Yes it works with saveoorUpdate method and updates the already existing record. But I am still not clear why session.save does not do the same thing. According to the defination of the save command it should update the already existing record if the id is not null or 0.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 02, 2007 6:45 am 
Beginner
Beginner

Joined: Thu Feb 01, 2007 3:08 am
Posts: 20
Since the generator class is native, whenever u call save , it will create a new id and save it to database.
Try the same example by changing the ganerator class to assigned .
In this case , session2.save will give u the error.

<id name="id" column="MESSAGE_ID">
<generator class="native" />
</id>


PS : please don't forget to give credits below if you found this answer useful :)


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 02, 2007 6:49 am 
Newbie

Joined: Thu Feb 22, 2007 9:49 am
Posts: 9
You do not have a "type" attribute specified in the mapping for the id, not quite sure what Hibernate would do in that circumstance, but my guess is that it reverts to not storing the id outwith its own reference, so the internal copy of the ID within your instance will never be set.

Try:

Code:
<?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 package="org.hibernate.hello">
   <class name="Message" table="MESSAGES" >
      <id name="id" type="long" column="MESSAGE_ID">
         <generator class="native" />
      </id>
      <property name="text" column="MESSAGE_TEXT"/>
     
      <property name="description" column="MESSAGE_DESCRIPTION"/>
   </class>
</hibernate-mapping>


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 02, 2007 6:54 am 
Beginner
Beginner

Joined: Mon Mar 14, 2005 9:07 am
Posts: 27
Tried by adding type="long" to the id tag in the hbm.xml. But the same problem still persists. Instead of updating it is adding a new record.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 02, 2007 7:01 am 
Newbie

Joined: Thu Feb 22, 2007 9:49 am
Posts: 9
Could you paste in the source for the Message class itself please?

The code above has the HelloManager class, but not the actual Message class definition.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 02, 2007 7:14 am 
Beginner
Beginner

Joined: Mon Mar 14, 2005 9:07 am
Posts: 27
Here it is-

Code:
package org.hibernate.hello;

public class Message {
   private Long id;

   private String text;

   private String description;

   public String getDescription() {
      return description;
   }

   public void setDescription(String description) {
      this.description = description;
   }

   public Message() {
   }

   public Long getId() {
      return id;
   }

   public void setId(Long id) {
      this.id = id;
   }

   public String getText() {
      return text;
   }

   public void setText(String text) {
      this.text = text;
   }

   public boolean equals(Message message) {
      System.out.println("equals ......................");
      if (this == message) {
         return true;
      }
      if (message == null || !(message instanceof Message)) {
         return false;
      }
      if (this.text != null ? !this.text.equals(message.text)
            : message.text != null) {
         return false;
      }
      if (this.description != null ? !this.description
            .equals(message.description) : message.description != null) {
         return false;
      }
      if (null != id ? !id.equals(message.getId()) : null != message.getId()) {
         return false;
      } else {
         return true;
      }
   }

   public int hashCode() {
      return null != id ? id.hashCode() : super.hashCode();
   }
}


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 02, 2007 8:05 am 
Newbie

Joined: Thu Feb 22, 2007 9:49 am
Posts: 9
Hmm, I can't see anything wrong with the Message class. I can only assume that Hibernate never uses the ID stored in the class to check whether its a new or existing entry, and instead keeps an internal reference to all objects owned by a paritcular Session, which would mean saveOrUpdate() is the only viable solution for effectively updating a single instance across multiple Sessions.

The documentation for saveOrUpdate() does seem to explicitly point out that the purpose of the method is to allow persistent instances to cross the session boundary, so this seems to be the way to go.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 03, 2007 2:02 am 
Beginner
Beginner

Joined: Mon Mar 14, 2005 9:07 am
Posts: 27
I have one more query but when I am trying to post a new query it says atleast 1 credit required. How can I get a credit?


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