解释问题
请查看下面的代码,我正在使用@Version annonation并使用两个java类:一个用于保存Student实例,另一个用于更新同一个Student实例。我从实例本身提供Id值。在第一次更新时,学生姓名的值会更新,并且版本也会增加1,但如果它再次尝试更改学生姓名:我收到以下异常。请帮忙!!!
**Student.java**
package com.emb.hib;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Version;
@Entity
@Table(name = "STUDENTS")
public class Student {
@Id
@Column(name = "STUD_ID")
private int studId;
@Column(name = "STUD_NAME")
private String StudName;
@Version
@Column(name = "VERSION", nullable = false, columnDefinition = "integer DEFAULT 0")
private long version;
public Student(int studId, String studName) {
super();
this.studId = studId;
StudName = studName;
}
public int getStudId() {
return studId;
}
public void setStudId(int studId) {
this.studId = studId;
}
public String getStudName() {
return StudName;
}
public void setStudName(String studName) {
StudName = studName;
}
public long getVersion() {
return version;
}
public void setVersion(long version) {
this.version = version;
}
}
**StudentRecSave.java**
package com.emb.hib;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
public class StudentRecSave {
public static void main(String[] args) {
StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder()
.configure("hibernate.cfg.xml").build();
Metadata metadata = new MetadataSources(standardRegistry)
.getMetadataBuilder().build();
SessionFactory sessionFactory = metadata.getSessionFactoryBuilder()
.build();
Session session = sessionFactory.openSession();
Student rukmini = new Student(1, "Rukmini");
Transaction tx = session.beginTransaction();
session.persist(rukmini);
tx.commit();
session.close();
System.out.println("Student record saved");
}
}
**StudentRecUpdate.java**
package com.emb.hib;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
public class StudentRecUpdate {
public static void main(String[] args) {
StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder()
.configure("hibernate.cfg.xml").build();
Metadata metadata = new MetadataSources(standardRegistry)
.getMetadataBuilder().build();
SessionFactory sessionFactory = metadata.getSessionFactoryBuilder()
.build();
Session session = sessionFactory.openSession();
Student rukmini = new Student(1, "Rukmini Iyer");
Transaction tx = session.beginTransaction();
session.saveOrUpdate(rukmini);
tx.commit();
session.close();
System.out.println("Student record updated");
}
}
**hibernate.cfg.xml**
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="hibernate.connection.driver_class">
com.mysql.jdbc.Driver
</property>
<!-- Assume test is the database name -->
<property name="hibernate.connection.url">
jdbc:mysql://localhost/test
</property>
<!-- <property name="hibernate.connection.username">root</property> -->
<!--<property name="hibernate.connection.password">root123</property> -->
<property name="hbm2ddl.auto">update</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="use_sql_comments">true</property>
<!-- List of XML mapping files -->
<mapping package="com.emb.hib" />
<mapping class="com.emb.hib.Student" />
</session-factory>
</hibernate-configuration>
控制台输出
Nov 16, 2016 12:42:12 PM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {5.0.5.Final}
Nov 16, 2016 12:42:12 PM org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
Nov 16, 2016 12:42:12 PM org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
Nov 16, 2016 12:42:12 PM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
Nov 16, 2016 12:42:12 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH10001002: Using Hibernate built-in connection pool (not for production use!)
Nov 16, 2016 12:42:12 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001005: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost/test]
Nov 16, 2016 12:42:12 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001001: Connection properties: {}
Nov 16, 2016 12:42:12 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001003: Autocommit mode: false
Nov 16, 2016 12:42:12 PM org.hibernate.engine.jdbc.connections.internal.PooledConnections <init>
INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
Nov 16, 2016 12:42:13 PM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
Nov 16, 2016 12:42:13 PM org.hibernate.engine.jdbc.env.internal.LobCreatorBuilderImpl useContextualLobCreation
INFO: HHH000423: Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4
Nov 16, 2016 12:42:13 PM org.hibernate.tuple.PojoInstantiator <init>
INFO: HHH000182: No default (no-argument) constructor for class: com.emb.hib.Student (class must be instantiated by Interceptor)
Nov 16, 2016 12:42:13 PM org.hibernate.tuple.PojoInstantiator <init>
INFO: HHH000182: No default (no-argument) constructor for class: com.emb.hib.Person (class must be instantiated by Interceptor)
Nov 16, 2016 12:42:13 PM org.hibernate.tool.hbm2ddl.SchemaUpdate execute
INFO: HHH000228: Running hbm2ddl schema update
Hibernate:
/* get current state com.emb.hib.Student */ select
student_.STUD_ID,
student_.STUD_NAME as STUD_NAM2_1_,
student_.VERSION as VERSION3_1_
from
STUDENTS student_
where
student_.STUD_ID=?
Hibernate:
/* update
com.emb.hib.Student */ update
STUDENTS
set
STUD_NAME=?,
VERSION=?
where
STUD_ID=?
and VERSION=?
Nov 16, 2016 12:42:13 PM org.hibernate.internal.SessionImpl$5 mapManagedFlushFailure
ERROR: HHH000346: Error during managed flush [Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1]
Exception in thread "main" 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:67)
at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:54)
at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:46)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3070)
at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2949)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3329)
at org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:145)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:560)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:434)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:337)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1282)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:465)
at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2963)
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2339)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:485)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:146)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$100(JdbcResourceLocalTransactionCoordinatorImpl.java:38)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:230)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:65)
at com.emb.hib.StudentRecUpdate.main(StudentRecUpdate.java:27)