5.1 Az adatváltozás időpontja
Ha sok éven át tárol különféle rekordokat egy adatbázisban, gyakran két kérdés merül fel:
- Mikor került ez a bejegyzés az adatbázisba?
- Mikor változtatták meg utoljára ezt a bejegyzést?
Ezek olyan gyakori feladatok, hogy az adatbázis szinte minden táblájához két oszlop kerül hozzáadásra:
- létre_idő
- frissített_idő
Az első a rekord létrehozásának dátumát és időpontját, a második pedig az utolsó módosítás dátumát és időpontját tárolja. És minden entitásosztálynak vannak mezői:
@Entity
@Table(name = "entities")
public class Entity {
...
@Column(name="created_time")
private Date created;
@Column(name="updated_time")
private Date updated;
}
A Hibernate minden feladatot képes ellenőrizni, ha az adatbázisban lévő objektumok két megjegyzéssel @CreationTimestamp
és @UpdateTimestamp
.
Példa:
@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;
}
Az ezekkel a megjegyzésekkel jelölt oszlopok mindig az objektum létrehozásának és utolsó módosításának pontos idejét tárolják.
5.2 @PrePersist annotáció
Ha bonyolultabb szkriptekre van szüksége egy objektum idejének szabályozásához, akkor a Hibernate erre az esetre is rendelkezik megjegyzésekkel. Megjelölhetik az osztálymetódusokat, és a Hibernate ezeket a metódusokat hívja meg, amikor elmenti az objektumot az adatbázisba. Összesen 7 ilyen megjegyzés van:
@PrePersist | Az objektum adatbázisba mentése előtt hívják meg. (SQL INSERT) |
@PostPersist | Az objektum adatbázisba mentése után azonnal meghívódik. (SQL INSERT) |
@PreRemove | Meghívás az adatbázisban lévő objektum törlése előtt. |
@PostRemove | Egy objektum adatbázisból való törlése után hívódik meg. |
@PreUpdate | Az adatbázisban lévő objektum frissítése (SQL UPDATE) előtt meghívva. |
@PostUpdate | Az adatbázisban lévő objektum frissítése (SQL UPDATE) után hívják meg. |
@postload | Meghívás az objektum adatbázisból való betöltése után. |
Írjunk egy példát, ahol megmondjuk egy osztálynak az objektumok létrehozásának és frissítésének pontos idejét:
@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();
}
}
Ha a Hibernate először menti el az objektumot, akkor meghívja a -val jelölt metódust @PrePersist
. Ha frissít egy meglévő objektumot az adatbázisban, akkor meghívja a megjegyzéssel jelölt metódust @PreUpdate
.
5.3 EntityListeners hozzáadása
Ha valóban szüksége van rá, akkor elkülönítheti a Hibernate által meghívott metódusokat attól az objektumtól, amelyen meghívja őket. A JPA specifikáció lehetővé teszi olyan figyelőosztályok deklarálását, amelyek bizonyos időpontokban meghívásra kerülnek az entitás objektumok feldolgozása során.
Ha sok hasonló entitás objektummal rendelkezik, akkor áthelyezhet néhányat az alaposztályba, és hozzáadhat egy figyelőt, amely szabályozza a viselkedésüket. Példa:
@MappedSuperclass
public abstract class BaseEntity {
private Timestamp createdOn;
private Timestamp updatedOn;
}
@Entity
public class User extends BaseEntity {
@Id
private Long id;
private String name;
}
Ezután a BaseEntity osztályhoz létrehozhat egy speciális figyelő osztályt:
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) );
}
}
És összekapcsolhatja a User osztályt és a figyelőjét néhány megjegyzés segítségével:
@Entity
@EntityListeners(class= TimeEntityListener.class)
public class User extends BaseEntity {
@Id
private Long id;
private String name;
}
GO TO FULL VERSION