Showing posts with label hibernate. Show all posts
Showing posts with label hibernate. Show all posts

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.

Thursday, 21 July 2011

Introduction

I am a java developer, specialising in web services, from Bristol, in the UK. I work as an application modernisation specialist for Desynit. This blog is for me to share and develop ideas and solutions discovered along the way.

My current projects are focused on the AppFuse2 Java platform, with Spring and Hibernate, and the DOJO javascript suite, including work with the groundbreaking dojox.mobile API for developing web services for mobile phones.

If any of this sounds like it might be of interest to you, bookmark or follow me now; and check back for future posts!