私は現在、私のプロジェクトで楽観的ロック管理に取り組んでいます。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 はスローされません。マージの直前にアコードに含まれていたバージョンが、私の 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 がスローされます。
問題
バージョンは、私の DTO からではなく、Hibernate キャッシュから取得されます。したがって、エンティティをデタッチすると、すべてが機能します(推測します)が、それはしたくありません(開発者がそれを忘れた場合のバグの原因...)。
何か考えはありますか?