5.1 Veri değişikliği zamanı
Çeşitli kayıtları yıllarca bir veritabanında sakladığınızda, genellikle iki soru ortaya çıkar:
- Bu giriş veri tabanına ne zaman eklendi?
- Bu giriş en son ne zaman değiştirildi?
Bunlar o kadar sık yapılan görevlerdir ki, veritabanındaki hemen hemen her tabloya iki sütun eklenir:
- yaratılan_zaman
- update_time
İlki, kaydın oluşturulduğu tarih ve saati, ikincisi ise en son değiştirildiği tarih ve saati saklar. Ve her Entity sınıfının alanları vardır:
@Entity
@Table(name = "entities")
public class Entity {
...
@Column(name="created_time")
private Date created;
@Column(name="updated_time")
private Date updated;
}
Hibernate, veritabanındaki nesnelerin iki ek açıklama @CreationTimestamp
ve @UpdateTimestamp
.
Örnek:
@Entity
@Table(name = "entities")
public class Entity {
...
@CreationTimestamp
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "create_date")
private Date createDate;
@UpdateTimestamp
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "modify_date")
private Date modifyDate;
}
Bu ek açıklamalarla işaretlenen sütunlar, her zaman nesnenin oluşturulduğu ve en son değiştirildiği zamanı doğru şekilde saklayacaktır.
5.2 @PrePersist açıklaması
Bir nesnenin zamanını kontrol etmek için daha karmaşık betiklere ihtiyacınız varsa, Hibernate'de bu durum için de ek açıklamalar bulunur. Sınıf yöntemlerini işaretleyebilirler ve Hibernate, nesneyi veritabanına kaydettiğinde bu yöntemleri çağırır. Toplamda bu tür 7 ek açıklama vardır:
@PrePersist | Nesne veritabanına kaydedilmeden önce çağrılır. (SQL EKLEYİN) |
@PostPersist | Nesne veritabanına kaydedildikten hemen sonra çağrılır. (SQL EKLEYİN) |
@Kaldırma Öncesi | Veritabanındaki bir nesneyi silmeden önce çağrılır. |
@PostRemove | Veritabanından bir nesne silindikten sonra çağrılır. |
@Ön Güncelleme | Veritabanındaki bir nesneyi güncellemeden (SQL UPDATE) önce çağrılır. |
@Güncelleme Sonrası | Veritabanındaki bir nesnenin güncellenmesinden (SQL UPDATE) sonra çağrılır. |
@PostLoad | Nesne veritabanından yüklendikten sonra çağrılır. |
Bir sınıfa nesnelerini oluşturması ve güncellemesi için doğru zamanı söylediğimiz bir örnek yazalım:
@Entity
@Table(name = "entities")
public class Entity {
...
@Column(name="created_time")
private Date created;
@Column(name="updated_time")
private Date updated;
@PrePersist
protected void onCreate() {
created = new Date();
}
@PreUpdate
protected void onUpdate() {
updated = new Date();
}
}
Hazırda bekletme nesneyi ilk kez kaydederse, ile açıklamalı yöntemi çağırır @PrePersist
. Veritabanında var olan bir nesneyi güncellerse, ek açıklama ile işaretlenmiş yöntemi çağırır @PreUpdate
.
5.3 EntityListener'larımızı ekleme
Gerçekten ihtiyacınız varsa, Hibernate'in çağırdığı yöntemleri, onları çağırdığı nesneden ayırabilirsiniz. JPA belirtimi, Entity nesnelerini işlerken belirli zamanlarda çağrılacak dinleyici sınıflarını bildirmenizi sağlar.
Çok sayıda benzer Entity nesneniz varsa, bazılarını temel sınıfa taşıyabilir ve davranışlarını kontrol edecek bir Dinleyici ekleyebilirsiniz. Örnek:
@MappedSuperclass
public abstract class BaseEntity {
private Timestamp createdOn;
private Timestamp updatedOn;
}
@Entity
public class User extends BaseEntity {
@Id
private Long id;
private String name;
}
Ardından, BaseEntity sınıfı için özel bir dinleyici sınıfı oluşturabilirsiniz:
public class TimeEntityListener {
public void onPersist(Object entity) {
if (entity instanceof BaseEntity) {
BaseEntity baseEntity = (BaseEntity) entity;
baseEntity.createdOn = now();
}
}
public void onUpdate(Object entity) {
if (entity instanceof BaseEntity) {
BaseEntity baseEntity = (BaseEntity) entity;
baseEntity.updatedOn = now();
}
}
private Timestamp now() {
return Timestamp.from(LocalDateTime.now().toInstant(ZoneOffset.UTC) );
}
}
Ve birkaç ek açıklama kullanarak User sınıfını ve dinleyicisini bağlayabilirsiniz:
@Entity
@EntityListeners(class= TimeEntityListener.class)
public class User extends BaseEntity {
@Id
private Long id;
private String name;
}