不幸的是,(至少对于Hibernate而言)
@Version手动更改字段不会使它成为另一个“版本”。即乐观并发检查是针对读取实体时获取的版本值而不是针对实体更新时的版本字段进行的。
例如
这会工作
Foo foo = fooRepo.findOne(id); // assume version is 2 herefoo.setSomeField(....);// Assume at this point of time someone else change the record in DB, // and incrementing version in DB to 3fooRepo.flush(); // forcing an update, then Optimistic Concurrency exception will be thrown
但是这不起作用
Foo foo = fooRepo.findOne(id); // assume version is 2 herefoo.setSomeField(....);foo.setVersion(1);fooRepo.flush(); // forcing an update, no optimistic concurrency exception // Coz Hibernate is "smart" enough to use the original 2 for comparison
有一些解决方法。最简单的方法可能是自己实施乐观并发检查。我曾经有一个工具来进行“
DTO到模型”数据填充,并且在那里放置了版本检查逻辑。另一种方法是将逻辑放在
setVersion()其中,而不是真正设置版本,而是执行版本检查:
class User { private int version = 0; //..... public void setVersion(int version) { if (this.version != version) { throw new YourOwnOptimisticConcurrencyException(); } } //.....}


