Hibernate @Version – OptimisticLockException
Hibernate, @Version ile işaretlenen kolon sayesinde bir oturumda açılan varlık nesnesinin, diğer bir oturumda değiştirilmesine izin vermeyerek OptimisticLockException fırlatır. Bu istisna yakalanarak ilgili işlemler yapılabilir. Değişiklik yapılmak istenen varlık nesnesinin başka bir oturumda değiştirildiği belirtilerek kullanıcı yönlendirilebilir örneğin.
@Version ile işaretlenmiş kolon Long, Integer veya TimeStamp tipinde olabilir. Hibernate bu nesne (veritabanında karşılığı olan satır) üzerinde gerçekleştirilen persist() ve sonraki her bir merge() işlemi ile beraber versiyon kolonunun değerini bir arttırır.
@Entity
public class Flight implements Serializable {
…@Version
@Column(name=”OPTLOCK”)
private Integer version {
…
}}
Şöyle ifade edebiliriz sanırım; Nesnenin veritabanından okudunduğu zamanki versiyonuna ilkVersiyon, yapılan değişiklikler veritabanına yansıtılmadan hemen evvelki versiyona sonVersiyon dersek Hibernate API’nin değişiklikleri veritabanına yansıtan metodu olan EntityManager.flush() ilkVersiyon.equals(sonVersiyon) kontrolu yapar. İki versiyon değeri eşitse değişiklikleri veritabanına yansıtır, farklıysa -ki bu ilgili satırın bir başka oturumda değiştirildiği anlamına gelir- OptimisticLockException fırlatır. Bu durumdaki nesne “stale object” tanımına girer.
Bahsettiğim hata;
javax.ejb.EJBException: javax.persistence.OptimisticLockException: org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)
gibi bir hatadır.
Burada dikkat edilmesi gereken EntityManager sınıfının executeUpdate() metodunun bu versiyon alanının değerini arttırmadığı. Bu yüzden ilgili varlık sınıfları için böylesi bir işlem yapılmadığına dikkat etmek gerekiyor ki neden OptimisticLockException almıyoruz diye debelenmeyelim.
Ve java gurusu abilerimizden Hakan Uygun der ki, bu yöntem ilgili nesneyi barındıran her veritabanı işlemi için (yukarıdaki gibi bir versiyon numarası eşitliği gerçekleştirmek adına) bir sorgu daha çekmek demek. Dolayısıyla bu kolonu öyle ilgili ilgisiz her varlık sınıfına eklememek gerekir. Ayrıca bir çözüm değil, sadece böylesi eş zamanlı düzenleme işlemlerinde alınabilecek hataları engellemek adına uygulanabilecek bir yöntemdir.
Konuyla ilgili daha detaylı bilgi için şuraya bakılabilir.
Son Yorumlar