Thursday 25 August 2011

Hibernate Exception: "a different object with the same identifier value was already associated with the session"

I recently encountered this Hibernate exception whilst writing some routine user management functionality, and trying to save a user object back to the database.


org.hibernate.NonUniqueObjectException: A different object with the same
identifier value was already associated with the session [objectId]


I then found two potential causes of this, and by explaining them here, you should be able to check for and solve them if you're having this trouble.

The first cause is from duplicating a Hibernate object in memory, and trying to save either copy. Such as:

public void UpdateLastLogin(int userId) {

    User original = userDao.get(userId);

    User updated = new User();
    updated.setId(original.setId());
    updated.setName(original.getName());
    updated.setLastLogin(new Date());
    userDao.save(updated);
}

The user "original" is loaded into the Hibernate cache by the get() method, but then we create a new user, assign it the same primary key (ID) and try to save it. Hibernate throws a NonUniqueObjectException because "original" is still in the cache and could cause concurrency errors down the line.

The second cause of this error I have discovered comes from the Appfuse framework. Calling the genericDao.exists() method to check the presence of a key in the database actually loads it into the Hibernate cache as well. This means if you have another instance of the object due to be saved, you will invalidate it through this NonUniqueObjectException.

An example of this case could be as follows:

    
public void newEmail(User user) {
    
    boolean toSave = false;
    if(!userDao.exists(user.getUserId())) {
        toSave = true;
    } else {
        String currentEmail = userDao.getUserEmail(user.getId());
        if (!currentEmail.equals(user.getEmail())) {
            toSave = true;
        }
    }
    
    if(toSave) {
        ecmUserDao.save(user);
    }
}

So if you are getting NonUniqueObjectExceptions. Look through your code for either of these cases, and consider carefully whether you are, and whether you need to duplicate Hibernate controlled objects.

4 comments:

  1. Very cool solution and I am of the opinion that it will definitely be useful in subsequent implementations. Besides, I have been using cloud native application development for some time because I know how good it is. For me, the most important thing is that a given native application is simply very useful.

    ReplyDelete
  2. Amazing Article! Your informations like a charm. I have read 3 books on Android app development , nowhere I can find these instructions. Lots of thanks for this excellent tutorial. You saved my time hours. THANKS. Do you know about any Top mobile App Development companies in Dubai?

    ReplyDelete