Java OptimisticLockingFailureException:批更新返回意外的行计数
在SpringWebMVC应用程序中,我有一个简单的父-子-一对多单向关系。我有两个RESTful api:POST和PUT 母公司:Java OptimisticLockingFailureException:批更新返回意外的行计数,java,jpa,spring-data,Java,Jpa,Spring Data,在SpringWebMVC应用程序中,我有一个简单的父-子-一对多单向关系。我有两个RESTful api:POST和PUT 母公司: @Entity @EqualsAndHashCode(exclude = {"children", "id"}) public class Parent { @Id @Column @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;
@Entity
@EqualsAndHashCode(exclude = {"children", "id"})
public class Parent {
@Id
@Column
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "PARENT_ID", nullable = false, updatable = false)
private Set<Child> children = new HashSet<>();
}
控制器:
@RestController
@RequestMapping("/parent")
public class Controller {
@Autowired
private ServiceImpl serviceImpl;
@PostMapping
public ResponseEntity<Parent> post(@RequestBody final Parent parent) {
return new ResponseEntity<Parent>(serviceImpl.create(parent), HttpStatus.OK);
}
@PutMapping
public ResponseEntity<Parent> put(@RequestBody final Parent parent) {
return new ResponseEntity<Parent>(serviceImpl.update(parent), HttpStatus.OK);
}
}
我有一个父级存储库。
作为POST api的一部分,我一起创建父级和子级
我需要通过PUT更新家长和孩子。
但是,当我尝试替换已创建父项的一个或多个子项时,我会收到错误:
{"timestamp":"2019-05-27T20:21:53.451+0000","status":500,"error":"Internal Server Error","message":"Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1; nested exception is org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1","path":"/parent"}
只有在使用多个线程执行简单的JMETER perf测试时,才会出现此问题
如果我将CascadeType更改为在关系的父端合并,则更新工作正常,但新实体的持久性将通过Post api失败。存在乐观锁定,以防止一行被多个事务更新。您是否试图通过Jmeter多次更新同一记录?
@Service
public class ServiceImpl implements inter {
@Autowired
ParentRepository repository;
public Parent create(Parent parent) {
return repository.save(parent);
}
@Transactional(readOnly = true)
public Parent findById(Long id) {
return repository.findById(id).orElseThrow(IllegalArgumentException::new);
}
@Transactional
public Parent update(Parent toUpdate) {
Parent retrieved = this.findById(toUpdate.getId());
retrieved.getChildren().retainAll(toUpdate.getChildren());
retrieved.getChildren().addAll(toUpdate.getChildren());
return repository.save(retrieved);
}
}
{"timestamp":"2019-05-27T20:21:53.451+0000","status":500,"error":"Internal Server Error","message":"Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1; nested exception is org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1","path":"/parent"}