StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1

Siddu picture Siddu · Jan 26, 2017 · Viewed 7.5k times · Source

I found too many answers in this site, but i am unable to resolve the error. Please help me to come out of this problem. The exception is thrown when (Transaction) tx.commit is executed but I don't know why.If I comment tx.commit, the Employee values will be inserted into table but Certificate values will not be inserted into certificate table.Please check it.

Full Exception

     Hibernate: 
    /* insert mapping.set.Employee2
        */ insert 
        into
            Employee2
            (fName, lName, salary) 
        values
            (?, ?, ?)
14:47:29,983 DEBUG StringType:80 - binding 'ABC' to parameter: 1
14:47:29,984 DEBUG StringType:80 - binding 'xyz' to parameter: 2
14:47:29,984 DEBUG IntegerType:80 - binding '10000' to parameter: 3
Hibernate: 
    /* update
        mapping.set.Certificate */ update
            Certifiedemployee 
        set
            CertificateName=? 
        where
            id=?
14:47:29,996 DEBUG StringType:80 - binding 'Java' to parameter: 1
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
    at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:61)
    at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:46)
    at org.hibernate.jdbc.BatchingBatcher.checkRowCounts(BatchingBatcher.java:68)
    at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:242)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:235)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:140)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
    at mapping.set.EmployeeDetails.addEmployee(EmployeeDetails.java:53)
    at mapping.set.EmployeeDetails.main(EmployeeDetails.java:36)
14:47:29,997 DEBUG IntegerType:80 - binding '111' to parameter: 2
14:47:29,999 ERROR AbstractBatcher:51 - Exception executing batch: 
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
    at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:61)
    at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:46)
    at org.hibernate.jdbc.BatchingBatcher.checkRowCounts(BatchingBatcher.java:68)
    at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:242)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:235)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:140)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
    at mapping.set.EmployeeDetails.addEmployee(EmployeeDetails.java:53)
    at mapping.set.EmployeeDetails.main(EmployeeDetails.java:36)
14:47:30,001 ERROR AbstractFlushingEventListener:301 - Could not synchronize database state with session
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
    at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:61)
    at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:46)
    at org.hibernate.jdbc.BatchingBatcher.checkRowCounts(BatchingBatcher.java:68)
    at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:242)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:235)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:140)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
    at mapping.set.EmployeeDetails.addEmployee(EmployeeDetails.java:53)
    at mapping.set.EmployeeDetails.main(EmployeeDetails.java:36)
Hibernate: 
    /* create one-to-many row mapping.set.Employee2.certificates */ update
        Certifiedemployee 
    set
        employee_id=? 
    where
        id=?
14:47:30,003 DEBUG IntegerType:80 - binding '7' to parameter: 1
14:47:30,004 DEBUG IntegerType:80 - binding '111' to parameter: 2
Hibernate: 
    /* create one-to-many row mapping.set.Employee2.certificates */ update
        Certifiedemployee 
    set
        employee_id=? 
    where
        id=?
14:47:30,004 DEBUG IntegerType:80 - binding '7' to parameter: 1
14:47:30,004 DEBUG IntegerType:80 - binding '111' to parameter: 2
14:47:30,010 ERROR AbstractBatcher:51 - Exception executing batch: 
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1

Class Employee

import java.util.Set;
@SuppressWarnings("rawtypes")    
public class Employee2 {     
    private int id;    
    private String firstName;    
    private String lastName;    
    private int salary;    
    private Set certificates;  
public Employee2() {    }
public Employee2(String firstName, String lastName, int salary) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.salary = salary;
}
}// Getters and setters are also present in the code

Certificate class

public class Certificate {    
    private int id;    
    private String name;    

    public Certificate() {  }
    public Certificate(int id, String name) {
        this.id = id;
        this.name = name;
    }
}// Getters and setters are also present in the code

Main class

public class EmployeeDetails {
    private static SessionFactory factory=null;
    public static void main(String[] args) {
        try{
            factory=new Configuration().configure().buildSessionFactory();
            System.out.println("Created session factory object");

        }catch(Throwable ex){
            System.err.println("Failed to create session factory object!\t"+ex);
        }
        EmployeeDetails emp=new EmployeeDetails();
        Set<Certificate> set1=new HashSet<Certificate>();
        Certificate c1=new Certificate(111, "Java");
        set1.add(c1);
        Integer empid1=emp.addEmployee("ABC","xyz",10000, set1);
        System.out.println("The id is"+empid1);
    }
    private Integer addEmployee(String firstName, String lastName, int salary,Set<Certificate> set1) {
        Integer id=null;
        Session session=factory.openSession();
        Transaction tx=null;
        try {
            tx=session.beginTransaction();
            Employee2 employee=new Employee2(firstName, lastName, salary);
            employee.setCertificates(set1);
            employee.setId(0);
            id=(Integer) session.save(employee);
            tx.commit();            
        } catch(HibernateException e) {
            e.printStackTrace();
        }finally{
            session.flush();
            session.close();
        }
        return id;
    }
}

Employee2.hbm.xml

<hibernate-mapping>
    <class name="mapping.set.Employee2" table="Employee2">
    <meta attribute="class-description">
        this class contains Employee certificate and other details
    </meta>
    <id name="id" type="int" column="empId">
    <generator class="native"></generator>
    </id>

    <set name="certificates" table="Certifiedemployee" cascade="save-update" >
    <key column="employee_id"/>
    <one-to-many class="mapping.set.Certificate"/>
    </set>

    <property name="firstName" column="fName" type="string"/>
    <property name="lastName" column="lName" type="string"/>
    <property name="salary" column="salary" type="int"/>
    </class>

    <class name="mapping.set.Certificate" table="Certifiedemployee">
    <meta attribute="class-description">
        This class contains certificate records 
    </meta>
    <id name="id" column="id" type="int">
    <generator class="native"/>
    </id>
    <property name="name" column="CertificateName" type="string"></property>
    </class>

</hibernate-mapping>

hibernate.cfg.xml

<session-factory>
        <!--Database connection Settings -->
        <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://127.0.0.1:3306/temp</property>
        <property name="connection.username">siddu</property>
        <property name="connection.password">siddu</property>
        <property name="show_sql">true</property>
        <property name="format_sql">true</property>
        <property name="use_sql_comments">true</property>

        <!-- <property name="hbm2ddl.auto">create</property> -->
        <!-- Use XML-based mapping metadata --> 
        <mapping resource="employee2.hbm.xml"/>
 </session-factory>

Thank you in advance

Answer

Siddu picture Siddu · Feb 7, 2017

The problem occurred because of setting id value by constructor

public Certificate(int id, String name) {
        this.id=id;
        this.name = name;
    }

in Certificate class and auto increment id value by

<id name="id" column="id" type="int">
    <generator class="native"/>
    </id>

in Employee2.hbm.xml file.Only one you have to use.After removing

<generator class="native"/>

from Employee2.hbm.xml file, I got following result in console:

Hibernate: 
    /* insert mapping.set.Employee2
        */ insert 
        into
            Employee2
            (fName, lName, salary) 
        values
            (?, ?, ?)
22:03:42,850 DEBUG StringType:80 - binding 'ABC' to parameter: 1
22:03:42,850 DEBUG StringType:80 - binding 'xyz' to parameter: 2
22:03:42,850 DEBUG IntegerType:80 - binding '10000' to parameter: 3
Hibernate: 
    /* get current state mapping.set.Certificate */ select
        certificat_.id,
        certificat_.CertificateName as Certific2_1_ 
    from
        Certifiedemployee certificat_ 
    where
        certificat_.id=?
22:03:42,850 DEBUG IntegerType:80 - binding '111' to parameter: 1
Hibernate: 
    /* insert mapping.set.Certificate
        */ insert 
        into
            Certifiedemployee
            (CertificateName, id) 
        values
            (?, ?)
22:03:42,866 DEBUG StringType:80 - binding 'Java' to parameter: 1
22:03:42,866 DEBUG IntegerType:80 - binding '111' to parameter: 2
Hibernate: 
    /* create one-to-many row mapping.set.Employee2.certificates */ update
        Certifiedemployee 
    set
        employee_id=? 
    where
        id=?
22:03:42,866 DEBUG IntegerType:80 - binding '1' to parameter: 1
22:03:42,866 DEBUG IntegerType:80 - binding '111' to parameter: 2
The id isnull