5.1 ডেটা পরিবর্তনের সময়
আপনি যখন অনেক বছর ধরে একটি ডাটাবেসে বিভিন্ন রেকর্ড সংরক্ষণ করেন, তখন প্রায়ই দুটি প্রশ্ন ওঠে:
- কখন এই এন্ট্রি ডাটাবেসে যোগ করা হয়েছিল?
- এই এন্ট্রি শেষ কখন পরিবর্তন করা হয়েছিল?
এগুলি এমন ঘন ঘন কাজ যা ডাটাবেসের প্রায় প্রতিটি টেবিলে দুটি কলাম যুক্ত করা হয়:
- তৈরি_সময়
- আপডেট_সময়
প্রথমটি রেকর্ডটি তৈরি করার তারিখ এবং সময় সঞ্চয় করে এবং দ্বিতীয়টি সর্বশেষ সংশোধিত তারিখ এবং সময় সংরক্ষণ করে৷ এবং প্রতিটি সত্তা ক্লাসের ক্ষেত্র রয়েছে:
@Entity
@Table(name = "entities")
public class Entity {
...
@Column(name="created_time")
private Date created;
@Column(name="updated_time")
private Date updated;
}
হাইবারনেট নিয়ন্ত্রণের সমস্ত কাজ করতে পারে যখন ডাটাবেসের বস্তু দুটি টীকা @CreationTimestamp
এবং @UpdateTimestamp
.
উদাহরণ:
@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;
}
এই টীকাগুলির সাথে চিহ্নিত কলামগুলি সর্বদা সঠিক সময় সংরক্ষণ করবে যখন বস্তুটি তৈরি করা হয়েছিল এবং কখন এটি শেষবার সংশোধন করা হয়েছিল৷
5.2 @PrePersist টীকা
কোনো বস্তুর সময় নিয়ন্ত্রণ করতে আপনার যদি আরও কিছু জটিল স্ক্রিপ্টের প্রয়োজন হয়, তাহলে হাইবারনেটের এই ক্ষেত্রেও টীকা আছে। তারা ক্লাস পদ্ধতি চিহ্নিত করতে পারে, এবং হাইবারনেট এই পদ্ধতিগুলিকে কল করবে যখন এটি বস্তুটিকে ডেটাবেসে সংরক্ষণ করে। মোট 7 টি এই ধরনের টীকা আছে:
@প্রিপারসিস্ট | বস্তুটি ডাটাবেসে সংরক্ষণ করার আগে কল করা হয়। (SQL ঢোকান) |
@PostPersist | অবজেক্ট ডাটাবেসে সংরক্ষিত হওয়ার সাথে সাথে কল করা হয়। (SQL ঢোকান) |
@প্রি-রিমুভ | ডাটাবেসের একটি বস্তু মুছে ফেলার আগে কল করা হয়। |
@পোস্ট সরান | ডেটাবেস থেকে একটি বস্তু মুছে ফেলার পরে কল করা হয়। |
@প্রি-আপডেট | ডাটাবেসের একটি অবজেক্ট (SQL আপডেট) আপডেট করার আগে কল করা হয়। |
@পোস্টআপডেট | ডাটাবেসের একটি বস্তুর আপডেট (SQL আপডেট) পরে কল করা হয়। |
@পোস্টলোড | ডেটাবেস থেকে অবজেক্ট লোড হওয়ার পরে কল করা হয়। |
আসুন একটি উদাহরণ লিখি যেখানে আমরা একটি ক্লাসকে তার বস্তুগুলি তৈরি এবং আপডেট করার সঠিক সময় বলি:
@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();
}
}
যদি হাইবারনেট প্রথমবারের জন্য বস্তুটিকে সংরক্ষণ করে, তাহলে এটি দ্বারা টীকা করা পদ্ধতিটিকে কল করবে @PrePersist
। যদি এটি ডাটাবেসের একটি বিদ্যমান বস্তু আপডেট করে, তাহলে এটি টীকা দিয়ে চিহ্নিত পদ্ধতিটিকে কল করবে @PreUpdate
।
5.3 আমাদের সত্তা শ্রোতাদের যোগ করা
আপনার যদি সত্যিই প্রয়োজন হয়, তাহলে আপনি হাইবারনেট কল করার পদ্ধতিগুলিকে যে বস্তুতে কল করে তা থেকে আলাদা করতে পারেন। JPA স্পেসিফিকেশন আপনাকে শ্রোতাদের ক্লাস ঘোষণা করতে দেয় যেগুলি সত্তা বস্তুগুলি প্রক্রিয়া করার সময় নির্দিষ্ট সময়ে কল করা হবে।
আপনার যদি অনেকগুলি অনুরূপ সত্তা অবজেক্ট থাকে, তাহলে আপনি তাদের কিছুকে বেস ক্লাসে নিয়ে যেতে পারেন এবং একটি লিসেনার যোগ করতে পারেন যা তাদের আচরণ নিয়ন্ত্রণ করবে। উদাহরণ:
@MappedSuperclass
public abstract class BaseEntity {
private Timestamp createdOn;
private Timestamp updatedOn;
}
@Entity
public class User extends BaseEntity {
@Id
private Long id;
private String name;
}
তারপর BaseEntity ক্লাসের জন্য, আপনি একটি বিশেষ শ্রোতা শ্রেণী তৈরি করতে পারেন:
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) );
}
}
এবং আপনি কয়েকটি টীকা ব্যবহার করে ব্যবহারকারী শ্রেণী এবং এর শ্রোতাকে সংযুক্ত করতে পারেন:
@Entity
@EntityListeners(class= TimeEntityListener.class)
public class User extends BaseEntity {
@Id
private Long id;
private String name;
}