我目前正在项目中进行乐观锁定管理。 我们使用JPA 2.0(hibernate-jpa2.0-api-1.0.1.Final),数据源由JBoss 7提供。
我做了什么
在我的实体" AccordSimple"我使用@Version注释:
@Entity
@Table(name = "AccordSimple")
public class AccordSimple {
@Id
@SequenceGenerator(name = "parametresubsidesequence",
sequenceName = "parametresubsidesequence", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "parametresubsidesequence")
private Long id;
// Optimistic lock.
@Version
private Long version;
}
这是我的AccordServiceImpl
public AccordDTO updateAccord(AccordDTO accordDTO) throws AppException {
AccordSimple accord = getAccordRepository().findByReference(
accordDTO.getAccordReference());
if (accord == null) {
return null;
}
// copy new values from the DTO...
accord.setVariable(accordDTO.getVariable());
// ...
// Set the version from the DTO (old version if someone changes before me!)
accord.setVersion(accordDTO.getVersion());
getAccordRepository().merge(accord);
return accordDTO;
}
这样,就不会抛出任何OptimisticLockException。即使合并之前在协议juste中包含的版本在我的DB中的版本之下。
我找到了原因。这是负责任的:
AccordSimple accord = getAccordRepository().findByReference(
accordDTO.getAccordReference());
因为如果我将我的方法改为:
public AccordDTO updateAccord(AccordDTO accordDTO) throws AppException {
AccordSimple accord = new AccordSimple(accordDTO.getAccordReference(), accordDTO.getVersion());
// copy new values from the DTO...
accord.setVariable(accordDTO.getVariable());
// ...
// Set the version from the DTO (old version if someone changes before me!)
accord.setVersion(accordDTO.getVersion());
getAccordRepository().merge(accord);
return accordDTO;
}
将抛出一个OptimisticLockException!
问题
该版本来自Hibernate缓存,而不是来自我的DTO。 因此,如果我分离实体,那么一切都会起作用(我猜)但是我不想这样做(如果开发者忘记它就会出现错误的来源......)。
你有什么想法吗?
答案 0 :(得分:1)
将帖子 可能的替代方案: 还没试过,你可以尝试一下:
在实体中保留一个额外的版本号,使用@PostLoad或额外的列映射,其中insertable = false,updateable = false。
让@PreUpdate方法检查版本字段和extra-version字段。如果它们不匹配,则抛出异常。
所有这些都可以放在基础模型类中。所以没有人会忘记把逻辑放在实体中:))
(原始信息)
这正是我在之前项目中遇到的问题。执行乐观锁验证时,Hibernate不会查看实体中的版本字段。
我解决这段时间的方法是在将DTO“合并”到实体时验证自己。那时,我有一个实用程序来映射DTO和实体之间的属性。版本检查只是DTO版本字段中的额外注释问题,而不是将值设置为相应实体的属性,我在不匹配时抛出异常。
可能不适用于你