StaleStateException:批量更新从更新 [0] 返回了意外的行数;实际行数:0;预期:1

Posted

技术标签:

【中文标题】StaleStateException:批量更新从更新 [0] 返回了意外的行数;实际行数:0;预期:1【英文标题】:StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1 【发布时间】:2017-01-26 10:11:24 【问题描述】:

我在此站点中找到了太多答案,但我无法解决错误。请帮助我摆脱这个问题。 执行 (Transaction) tx.commit 时抛出异常但不知道为什么进入证书表。请检查它。

完全异常

     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

班级员工

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

证书类

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

主类

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>

提前谢谢你

【问题讨论】:

【参考方案1】:

由于构造函数设置id值导致问题发生

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

在证书类中自动递增 id 值

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

在Employee2.hbm.xml文件中。只有一个你必须使用。删除后

<generator class="native"/>

从 Employee2.hbm.xml 文件中,我在控制台中得到以下结果:

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

【讨论】:

以上是关于StaleStateException:批量更新从更新 [0] 返回了意外的行数;实际行数:0;预期:1的主要内容,如果未能解决你的问题,请参考以下文章

org.hibernate.StaleStateException:批量更新从更新 [0] 返回了意外的行数;实际行数:0;预期的

org.hibernate.StaleStateException:批量更新从更新 [0] 返回了意外的行数;实际行数:0;预期:1

org.hibernate.StaleStateException:批量更新从更新 [0] 返回了意外的行数;实际行数:0;预期:1

org.hibernate.StaleStateException:批量更新从更新 [0] 返回了意外的行数;实际行数:0;预期:1

Session.flush() 导致 org.hibernate.StaleStateException:批量更新从更新返回了意外的行数:1 实际行数:0 预期:1

无法更新记录休眠