StaleObjectStateException is encountered when an id is not set

I have a DAO class with the following implementation:

@Override
    public void save(Employee emp) {        
        Session curSession = entityManager.unwrap(Session.class);       
        curSession.saveOrUpdate(emp);       
    }

and a service class with the below implementation:

@Override
    @Transactional
    public void save(Employee emp) {        
        employeeDAO.save(emp);
    }

When I execute this code it throws me a StaleObjectStateException – org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)

But if I set the id before calling the DAO class, it works fine –

@Override
    @Transactional
    public void save(Employee emp) {
        emp.setId(0);
        employeeDAO.save(emp);
    }

Entity Class –

@Entity
@Table(name="employee")
public class Employee {
    
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="id")
    private int id;
    
    @Column(name="first_name")
    private String firstName;
    
    @Column(name="last_name")
    private String lastName;
    
    @Column(name="email")
    private String email;
    
    public Employee() {     
    }

    public Employee(int id, String firstName, String lastName, String email) {
        super();
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
    }
//getters and setters for the fields are present

Can anyone help me understand what exactly is happening here?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

As I don’t know the state of your session and DB when you get to stale object exception, I cannot be sure. However, here are some possible solutions to your problem based on my educated guesses :

Refer to this question for characteristics of saveOrUpdate() : Hibernate saveOrUpdate behavior

  • if the object is already persistent in this session, do nothing
  • if another object associated with the session has the same identifier, throw an exception
  • if the object has no identifier property, save() it
  • if the object’s identifier has the value assigned to a newly instantiated object, save() it
  • if the object is versioned by a “version” or “timestamp”, and the version property value is the same value assigned to a newly
    instantiated object, save() it otherwise update() the object

Make sure you’re not calling saveOrUpdate() twice on the same object anywhere, as this will cause a stale object exception.

Secondly, refer to this question :
Hibernate saveOrUpdate fails when I execute it on empty table

This is by design.

Hibernate only decides based on the id if it should perform an update
or an insert. If it would consider what’s already there in the
database, it would have to perform an additional query, but it doesn’t
do this.

Ids are normally managed by Hibernate, unless you map it as
generator=”assigned” (don’t know how this looks using annotations). So
you shouldn’t just assign a value to it.

In this case, the Id is even given by the database. So if your
application would generate Ids at the same time, it would result in
duplicated Ids. (And most database do not allow inserting values to
auto columns, so it would technically be impossible to store your id).

If you want to generate your own Ids, use generator=”assigned”, and
store it using merge. This will do what you expect: it searches the
record in the database, when it exists it will update it, when not it
will insert it.

Because Hibernate doesn’t do a Select query to perform an update or insert, make sure you are not manually creating records in your DB for tables that are supposed to be managed by Hibernate. Create actual instances of objects and save test objects to your DB instead.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x