我正在使用Jersey + spring + hibernate4.17来开发api系统;问题是如果在同一时间调用cleaFields两次,第二次调用会抛出异常,如下所示,
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:81)
at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:73)
at org.hibernate.engine.jdbc.batch.internal.BatchingBatch.checkRowCounts(BatchingBatch.java:133)
at org.hibernate.engine.jdbc.batch.internal.BatchingBatch.performExecution(BatchingBatch.java:110)
at org.hibernate.engine.jdbc.batch.internal.BatchingBatch.doExecuteBatch(BatchingBatch.java:101)
at org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl.execute(AbstractBatchImpl.java:149)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.executeBatch(JdbcCoordinatorImpl.java:162)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:357)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:280)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:326)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1213)
Controller中的clearFields方法,
@Transactional(isolation=Isolation.REPEATABLE_READ)
public void clearFields(Integer userId) {
User user = this.userDao.get(userId);
user.getFields().clear();
userDao.flush(); //call the current session.flush(); this line can throw exception.
}
用户实体类
@Entity
@Table(name="users")
@NamedQuery(name="User.findAll", query="SELECT u FROM User u")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id", unique = true, nullable = false)
private int userId;
@OneToMany(mappedBy = "user", cascade = { CascadeType.ALL }, targetEntity = UserProfile.class, fetch = FetchType.LAZY, orphanRemoval=true)
@OrderBy("id")
private List<UserProfile> fields = new ArrayList<UserProfile>();
public User() {
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public List<UserProfile> getFields() {
return fields;
}
public void setFields(List<UserProfile> fields) {
this.fields = fields;
}
}
UserProfile类,
@Entity
@Table(name="user_profiles")
public class UserProfile implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
@Column(name="field_name")
private String fieldName;
@ManyToOne(targetEntity = User.class, fetch = FetchType.LAZY)
@JoinColumn(name="user_id")
private User user;
private String value;
public UserProfile() {
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFieldName() {
return this.fieldName;
}
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
public String getValue() {
return this.value;
}
public void setValue(String value) {
this.value = value;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
我做了一些研究,根本原因是如果第二次调用得到一些字段,并且在删除它们之前,第一次调用已经删除了数据库中的所有字段。
换句话说,第二次调用尝试删除一些已被其他人删除的记录。
我该如何解决这个问题?