-->
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.  [ 16 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Hibernate saveOrUpdate Not Working
PostPosted: Wed Feb 17, 2010 2:10 am 
Newbie

Joined: Wed Jan 20, 2010 11:12 am
Posts: 15
Hi all,
I am new user of hibernate, and getting confused with the working of saveOrUpdate().
I have read that saveOrUpdate() will update the table entry if there is a record present for that ID, and if the id is not present then it simply insert the record.
But this is not happening with me.
I have a Role Table like
Role_id | Role_Name | Create_Time | Create_User | Update_Time | Update_USer
1 Admin 12-02-2010 At null null

now when from the UI when an update is happen, I just use this,
Code:
roleObj.setRoleId(1);
roleObj.setUpdateTime(new Date());
roleObj.setupdateUser("at");

and at the DAO layer I am using
Code:
saveOrUpdate(roleObj)


and what happening is :
Role_id | Role_Name | Create_Time | Create_User | Update_Time | Update_USer
1 Admin null null 12-02-2010 at

i.e it is not updating the things,
Please help me out...


Top
 Profile  
 
 Post subject: Re: Hibernate saveOrUpdate Not Working
PostPosted: Wed Feb 17, 2010 2:37 am 
Senior
Senior

Joined: Tue Oct 28, 2008 10:39 am
Posts: 196
Why do you think Hibernate didn't perform an update? Update_Time and Update_User are changed. Create_Time and Create_User as well => they are set to null. The only thing that seems a little confusing is that the rolename is unchanged. Maybe you didn't show the complete code.

Do you think Hibernate has to show the statement in it' logs? Then you have to set the right property in your hibernate.cfg.xml, set show_sql to true.


Top
 Profile  
 
 Post subject: Re: Hibernate saveOrUpdate Not Working
PostPosted: Wed Feb 17, 2010 9:42 am 
Newbie

Joined: Wed Jan 20, 2010 11:12 am
Posts: 15
yes you are right in terms of saveOrUpdate() is doing something, but not according to my knowledge on that,
and
roleName is not changed because from the UI i am getting its value and it is common for adding a role or updating a role.
But In updation what i want to do is I Only want to update only those field which has been changed, e.g in my example only update_time and update_user will be changed, so only this columns should be updated not the create_user, and create_time.

and update query is also running and it is updating all the fields like,
update role... set create_user=?, create_time=?, update_time=?, update_user.......
it means it is updating all the things, while it should only update the update_time=?, update_user


Top
 Profile  
 
 Post subject: Re: Hibernate saveOrUpdate Not Working
PostPosted: Wed Feb 17, 2010 9:52 am 
Senior
Senior

Joined: Tue Oct 28, 2008 10:39 am
Posts: 196
You are looking for dynamic-update. Chapter 5.1.3 in the documentation.


Top
 Profile  
 
 Post subject: Re: Hibernate saveOrUpdate Not Working
PostPosted: Wed Feb 17, 2010 12:25 pm 
Newbie

Joined: Wed Jan 20, 2010 11:12 am
Posts: 15
thanks for your reply
but it won't works for me,
I have tried both
Code:
dynamic-update="true" select-before-update="true"


Code:
String editRole = "1";
        Role role = new Role();
        role.setShortName("shortText");
        role.setLongName("longText");
        if(editRole .equals("1")){
            role.setUpdateTime(new Date());
            role.setUpdateUser("At");
// 5 is the tuple Id which i want to update
            role.setPkDeductionStatusId(5);

        }else{
            role.setCreateTime(new Date());
            role.setCreateUser("Atul");
        }
        try {
           
            roleManager.addOrUpdateRole(role);
        } catch (ServiceException ex) {
            System.out.println(ex.getMessage());
        }
    }


Code:
<hibernate-mapping>
  <class name="com.deductions.model.Role" dynamic-update="true" select-before-update="true" table="lu_deduction_status_rad">
    <id name="roleId" type="java.lang.Integer">
      <column name="pk_role_id"/>
      <generator class="identity"/>
    </id>
   
    <property name="shortName" type="string">
      <column length="40" name="short_name" not-null="true"/>
    </property>
    <property name="longName" type="string">
      <column length="120" name="long_name"/>
    </property>
    <property name="createUser" type="string">
      <column length="100" name="create_user"/>
    </property>
    <property name="createTime" type="timestamp">
      <column length="0" name="create_time"/>
    </property>
    <property name="updateUser" type="string">
      <column length="100" name="update_user"/>
    </property>
    <property name="updateTime" type="timestamp">
      <column length="0" name="update_time"/>
    </property>
  </class>
</hibernate-mapping>


Please look into this code


and this is the Logs Hibernate
Code:
2 selects query fires and an update,
Hibernate: update role set create_user=?, create_time=?, update_time=? where pk_role_id=?


Top
 Profile  
 
 Post subject: Re: Hibernate saveOrUpdate Not Working
PostPosted: Wed Feb 17, 2010 1:58 pm 
Newbie

Joined: Wed Jan 20, 2010 11:12 am
Posts: 15
What i am noticing is, if the value of
create_user and create_time is being null then update query is generated like this,
Code:
update role set update_time=? where pk_role_id=?


and if the value of create_user and create time is filled previously then update query generated is like what i have posted in previous post..

But can't be able to identify why?
Do any one have the answer?


Top
 Profile  
 
 Post subject: Re: Hibernate saveOrUpdate Not Working
PostPosted: Wed Feb 17, 2010 2:58 pm 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
Calling saveOrUpdate() with a detached instance simply assumes that all properties has been modified since Hibernate doesn't know the initial state. Using the select-before-update option will not help, since it is only used to confirm that at least a few values has been changed.

The dynamic-update option only works when the entity was loaded by the session. Hibernate must know the initial state, otherwise it can't detect which properties that has been changed.

The code below should work no matter what the dynamic-update or select-before-update has been set to.
Code:
roleObj = (Role)session.get(Role.class, 1);
//roleObj = new Role();
//roleObj.setRoleId(1);
roleObj.setUpdateTime(new Date());
roleObj.setupdateUser("at");
session.getTransaction().commit();


There is a possibility that the following may work if dynamic-update has been enabled, but I am not 100% that there are no side-effects if things are more complicated than simple properties. For example, I don't know what will happen with cascades to associations or collections.

Code:
Role roleObj = new Role();
roleObj.setRoleId(1);
session.lock(roleObj, LockMode.NONE);
roleObj.setUpdateTime(new Date());
roleObj.setupdateUser("at");
session.getTransaction().commit();


The key to this is that the call to session.lock() associates the entity with the session and also sets the initial state. Modifications made after this are detected and if dynamic-update="true" only the modified properties are included in the SQL. I tried it once and it worked for simple properties, but it felt a bit unsafe with collections and associations, so I gave up the idea.


Top
 Profile  
 
 Post subject: Re: Hibernate saveOrUpdate Not Working
PostPosted: Thu Feb 18, 2010 1:52 pm 
Newbie

Joined: Wed Jan 20, 2010 11:12 am
Posts: 15
thanks nordborg,

But i do not want to do this,

Actually I am doing all these things through spring and hibernate, struts,
so at DaoImpl, what i am doing is just used a method like,
Code:
public class RoleDaoImpl extends GenericHibernateDAOImpl implements RoleDao {

    private static Logger LOGGER = Logger.getLogger(RoleDaoImpl.class);

    public void addRoleToUser(Role userRole) throws ServiceException {
        LOGGER.info("Going to add Role to User.");
        try {
            saveOrUpdate(userRole);
            LOGGER.info("added role to user.");
        } catch (Exception e) {
            LOGGER.error("Exception Occured in AddRoleToUser",e);
            e.printStackTrace();
        }
    }
//... more code goes here....
}

so from the front end i just made an roleObject and call the addRoleToUser(role) over the Dao.

This saveOrUpdate() method is defined in GenericHibernateDaoImpl which looks like
Code:
public class GenericHibernateDAOImpl<T, ID extends Serializable> implements
      GenericHibernateDAO<T, ID> {
        private Class<T> persistentClass;

   protected HibernateTemplate hibernateTemplate;

   public GenericHibernateDAOImpl() {
   }

   public GenericHibernateDAOImpl(Class<T> type) {
      /*
       * this.persistentClass = (Class<T>) ((ParameterizedType) getClass()
       * .getGenericSuperclass()).getActualTypeArguments()[0];
       */
      this.persistentClass = type;
   }

        public Session getSession(){
            return getHibernateTemplate().getSessionFactory().getCurrentSession();
        }

   public void setSessionFactory(SessionFactory sessionFactory) {
      this.hibernateTemplate = new HibernateTemplate(sessionFactory);
   }

   public HibernateTemplate getHibernateTemplate() {
      return this.hibernateTemplate;
   }

   /*
    * public Session getSession() { // return HibernateUtil.getSession();
    * return getHibernateTemplate().getSessionFactory().getCurrentSession(); }
    */

   public Class<T> getPersistentClass() {
      return persistentClass;
   }

   public T findById(ID id, boolean lock) {
      T entity;
      if (lock)
         entity = (T) getHibernateTemplate().load(getPersistentClass(), id,
               LockMode.UPGRADE);
      else
         entity = (T) getHibernateTemplate().load(getPersistentClass(), id);

      return entity;
   }

   public List<T> findByExample(T exampleInstance, String[] excludeProperty) {
      Criteria crit = getHibernateTemplate().getSessionFactory()
            .getCurrentSession().createCriteria(getPersistentClass());
      Example example = Example.create(exampleInstance);
      for (String exclude : excludeProperty) {
         example.excludeProperty(exclude);
      }
      crit.add(example);
      return crit.list();
   }

   public List<T> findByCriteria(DetachedCriteria criteria) {
      return getHibernateTemplate().findByCriteria(criteria);
   }
        public List<T> findByCriteria(DetachedCriteria criteria,int startIndex, int rowsToFetch) {
      return getHibernateTemplate().findByCriteria(criteria,startIndex,rowsToFetch);
   }
   public T save(T entity) {
      getHibernateTemplate().save(entity);
      return entity;
   }
        public T saveOrUpdate(T entity) {
      getHibernateTemplate().saveOrUpdate(entity);
      return entity;
   }

        public void delete(T entity) {
      getHibernateTemplate().delete(entity);
   }

   public void update(T entity) {
      getHibernateTemplate().update(entity);
   }

   public void flush() {
      getHibernateTemplate().flush();
   }

   public void clear() {
      getHibernateTemplate().clear();
   }


so i do not want to manually handle the transaction and session.
Any Idea after that?


Top
 Profile  
 
 Post subject: Re: Hibernate saveOrUpdate Not Working
PostPosted: Thu Feb 18, 2010 2:20 pm 
Newbie

Joined: Mon Feb 15, 2010 3:09 pm
Posts: 7
Hi all,

I noticed two things here: first you are setting the ID yourself and not letting Hibernate set the ID. If I am not completely mistaken (being new to Hibernate too) it will attempt an update if the ID is different to "unsaved_value". Don't you use the @Id and @GeneratedValue mapping on getId()?

Second, if the code you posted is complete it doesn't take me wonder that your creation_time is not modified - it simply ain't nowhere. You should set it in setUpdateTime() if it is null.


Top
 Profile  
 
 Post subject: Re: Hibernate saveOrUpdate Not Working
PostPosted: Thu Feb 18, 2010 2:54 pm 
Newbie

Joined: Wed Jan 20, 2010 11:12 am
Posts: 15
here is my model getId()
Code:
...Code
@Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "pk_role_id", unique = true, nullable = false)
    public Integer getPkRoleId() {
        return this.pkRoleId;
    }
.... code...


Now let me explain the flow,

I am displaying the roles at UI(after calling a method roleManager.listRoles()) , now from the ui an action can be taken an Update or a New Role. If Update is called then editRole=1
Code:
String editRole = "1";
        Role role = new Role();
        role.setShortName("textBox Value here");

        if(editRole .equals("1")){
            role.setUpdateTime(new Date());
            role.setUpdateUser("At");
// 5 is the tuple Id which i want to update
            role.setPkRoleId(5);

        }else{
            role.setCreateTime(new Date());
            role.setCreateUser("At");
        }
        try {
           //This will call the manager and then manager call the dao and finally call will go to //the DAO impl and addOrUpdate() method will be called at RoleDaoImpl.
            roleManager.addOrUpdateRole(role);
        } catch (ServiceException ex) {
            System.out.println(ex.getMessage());
        }
    }


DAO Impl is
Code:
public class RoleDaoImpl extends GenericHibernateDAOImpl implements RoleDao {

    private static Logger LOGGER = Logger.getLogger(RoleDaoImpl.class);

    public void addRoleToUser(Role userRole) throws ServiceException {
        LOGGER.info("Going to add Role to User.");
        try {
            saveOrUpdate(userRole);
            LOGGER.info("added role to user.");
        } catch (Exception e) {
            LOGGER.error("Exception Occured in AddRoleToUser",e);
            e.printStackTrace();
        }
    }
//... more code goes here....
}

any hellp after this?


Top
 Profile  
 
 Post subject: Re: Hibernate saveOrUpdate Not Working
PostPosted: Thu Feb 18, 2010 4:58 pm 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
You'll need to set all properties to the values you want. You can't just set a few of them and assume that Hibernate will figure out which ones to update and which ones to not update. null is NOT a special values in this sense.

Instead of:

Code:
Role role = new Role();
....
role.setPkRoleId(5);
...
roleManager.addOrUpdateRole(role);


do
Code:
Role role = roleManager.findById(5);
....


and nothing more is needed (assuming that your transaction is committed somewhere). Hibernate will automatically changes and save them to the database. No need to call saveOrUpdate() or any other method.


Top
 Profile  
 
 Post subject: Re: Hibernate saveOrUpdate Not Working
PostPosted: Thu Feb 18, 2010 5:51 pm 
Beginner
Beginner

Joined: Wed Nov 21, 2007 8:02 am
Posts: 48
update your saveOrupdate method like this

public T saveOrUpdate(T entity) {
return getHibernateTemplate().merge(entity);
}


and keep the dynamic-update=true, and you won't need that select-before-update on your mapping.

It works as expected without optimistic locking.


But I think if you have to enable optimistic locking, this won't work. Or you may have to implement the MergeEventListener to throw optimistic locking exception inthat case


Top
 Profile  
 
 Post subject: Re: Hibernate saveOrUpdate Not Working
PostPosted: Fri Feb 19, 2010 1:41 am 
Newbie

Joined: Wed Jan 20, 2010 11:12 am
Posts: 15
first of all I am very thankful to every body who contributed to solve the problem,
@kavithakaran: this also not works for me, but what i did is as nordborg has suggested and it worked for me.

But really i don't want to waste a database call to first fetch the record, and do the processing,
If i am telling Hibernate that i have updated this object's update time then why should he is not just updating that thing only by his Id. it should automatically fetch that tuple of Id 5, and then only update that column, if it found that create_user is having a value other than Null, then it should leave it as it is, and if it is Null then also leave it as it is.


Top
 Profile  
 
 Post subject: Re: Hibernate saveOrUpdate Not Working
PostPosted: Fri Feb 19, 2010 4:02 am 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
As I said before. Null is not a special value. It is part of the state of the entity and null values are saved to the database just as any other value. Null is not a signal to Hibernate that nothing has changed. If you are worried about database hits you should consider setting up a second-level cache.

If you really, really want the behavior that null=not changed you can maybe create an Interceptor and implement this in the findDirty() method. You need to complement this with dynamic-update="true" so that only the non-null properties are sent to the database. However, I have no idea what you should do if you ever want to store a null value in the database... The dynamic-update="true" option will also affect performance negative since Hibernate needs to rebuild the SQL for every update instead of using a pre-generated SQL. I would not recommend this solution.


Top
 Profile  
 
 Post subject: Re: Hibernate saveOrUpdate Not Working
PostPosted: Fri Feb 19, 2010 10:20 am 
Newbie

Joined: Wed Jan 20, 2010 11:12 am
Posts: 15
Thanks nordborg, for your explanation, and i got it correctly.

But Hibernate can't do the thing like, if for a column suppose create_user I am using a default value
Quote:
defualtValue
String, and by some property(in hbm) i tell hibernate that this will be my default value, so whenever you are going to update a tuple then check whether it is a default value or any other value? if it is not the defualt value then leave it as it is, why r u setting it to defualt Value. and if you find other value then the stored one then update that column.
do you agree with that?


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 16 posts ]  Go to page 1, 2  Next

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.