1. আপনার কী ডাটাবেস কলাম ব্যবহার করা উচিত
আপনার প্রথম প্রশ্নটি ছিল:
আপনি ডাটাবেসে কোন ডেটা প্রকারগুলি ব্যবহার করবেন (মাইএসকিউএল ধরে নিচ্ছেন, সম্ভবত জেভিএম ভিন্ন টাইম জোনে)? ডাটা টাইপগুলি কি টাইমজোন সচেতন হবে?
মাইএসকিউএলে, TIMESTAMPকলামের ধরণটি জেডিবিসি ড্রাইভার স্থানীয় সময় অঞ্চল থেকে ডাটাবেস টাইমজোনকে স্থানান্তরিত করে, তবে এটি কেবল টাইমস্ট্যাম্পগুলি সঞ্চয় করতে পারে '2038-01-19 03:14:07.999999, সুতরাং এটি ভবিষ্যতের পক্ষে সেরা পছন্দ নয়।
সুতরাং এর DATETIMEপরিবর্তে আরও ভাল ব্যবহার করুন, যার উপরের সীমানাটির সীমাবদ্ধতা নেই। তবে DATETIMEটাইমজোন সচেতন নয়। সুতরাং, এই কারণে, ইউটিসি ডাটাবেস সাইডে ব্যবহার করা এবং hibernate.jdbc.time_zoneহাইবারনেট সম্পত্তি ব্যবহার করা ভাল ।
hibernate.jdbc.time_zoneসেটিং সম্পর্কে আরও তথ্যের জন্য , এই নিবন্ধটি দেখুন ।
২. কী সত্তা সম্পত্তি প্রকার আপনি ব্যবহার করা উচিত
আপনার দ্বিতীয় প্রশ্নটি ছিল:
আপনি জাভাতে কোন ডেটা টাইপ ব্যবহার করবেন (তারিখ, ক্যালেন্ডার, দীর্ঘ, ...)?
জাভা সাইডে, আপনি জাভা 8 ব্যবহার করতে পারেন LocalDateTime। আপনি উত্তরাধিকারটিও ব্যবহার করতে পারেন Date, তবে জাভা 8 তারিখ / সময়ের ধরণগুলি অপরিবর্তনীয় হওয়ার কারণে আরও ভাল এবং লগ ইন করার সময় কোনও টাইমজোন স্থানীয় সময় অঞ্চলে স্থানান্তরিত করবেন না।
হাইবারনেট দ্বারা সমর্থিত জাভা 8 তারিখ / সময়ের ধরণ সম্পর্কে আরও তথ্যের জন্য, এই নিবন্ধটি দেখুন ।
এখন, আমরা এই প্রশ্নের উত্তরও দিতে পারি:
ম্যাপিংয়ের জন্য আপনি কোন টিকা ব্যবহার করবেন (উদাঃ @Temporal)?
আপনি যদি টাইমস্ট্যাম্প সত্তা সম্পত্তিটি ব্যবহার করতে LocalDateTimeবা java.sql.Timestampমানচিত্রের জন্য ব্যবহার করে থাকেন তবে আপনার @Temporalএইচআইবারনেট ইতিমধ্যে জানে যে এই সম্পত্তিটি জেডিবিসি টাইমস্ট্যাম্প হিসাবে সংরক্ষণ করা উচিত knows
কেবলমাত্র আপনি যদি ব্যবহার করছেন তবে আপনার এটিকে টীকাটি java.util.Dateনির্দিষ্ট করতে হবে @Temporal:
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "created_on")
private Date createdOn;
তবে আপনি যদি এটির মতো ম্যাপ করেন তবে এটি আরও ভাল:
@Column(name = "created_on")
private LocalDateTime createdOn;
অডিট কলামের মানগুলি কীভাবে উত্পন্ন করা যায়
আপনার তৃতীয় প্রশ্নটি ছিল:
টাইমস্ট্যাম্পগুলি সেট করার জন্য আপনি কাকে দায়বদ্ধ করবেন — ডাটাবেস, ওআরএম কাঠামো (হাইবারনেট), বা অ্যাপ্লিকেশন প্রোগ্রামার?
ম্যাপিংয়ের জন্য আপনি কোন টিকা ব্যবহার করবেন (যেমন @ টেম্পোরাল)?
আপনি এই লক্ষ্য অর্জন করতে পারেন এমন অনেকগুলি উপায় রয়েছে। আপনি ডাটাবেসটিকে এটি করার অনুমতি দিতে পারেন ..
create_onকলামের জন্য আপনি একটি DEFAULTডিডিএল সীমাবদ্ধতা ব্যবহার করতে পারেন , যেমন:
ALTER TABLE post
ADD CONSTRAINT created_on_default
DEFAULT CURRENT_TIMESTAMP() FOR created_on;
জন্য updated_onকলাম, আপনি একটি ডিবি ট্রিগার ব্যবহার কলাম মান সেট করতে পারে CURRENT_TIMESTAMP()প্রত্যেক সময় একটি প্রদত্ত সারি রুপান্তরিত করা হয়েছে।
অথবা, সেগুলি সেট করতে জেপিএ বা হাইবারনেট ব্যবহার করুন।
ধরে নেওয়া যাক আপনার নিম্নলিখিত ডাটাবেস সারণি রয়েছে:

এবং, প্রতিটি টেবিলের মতো কলাম রয়েছে:
created_by
created_on
updated_by
updated_on
হাইবারনেট @CreationTimestampএবং @UpdateTimestampটীকাগুলি ব্যবহার করা
হাইবারনেটটি @CreationTimestampএবং @UpdateTimestampটীকাগুলি সরবরাহ করে যা ম্যাপ created_onএবং updated_onকলামগুলিকে মানচিত্র করতে ব্যবহার করা যেতে পারে ।
আপনি @MappedSuperclassএকটি বেস বর্গ নির্ধারণ করতে ব্যবহার করতে পারেন যা সমস্ত সত্তা দ্বারা প্রসারিত হবে:
@MappedSuperclass
public class BaseEntity {
@Id
@GeneratedValue
private Long id;
@Column(name = "created_on")
@CreationTimestamp
private LocalDateTime createdOn;
@Column(name = "created_by")
private String createdBy;
@Column(name = "updated_on")
@UpdateTimestamp
private LocalDateTime updatedOn;
@Column(name = "updated_by")
private String updatedBy;
//Getters and setters omitted for brevity
}
এবং, সমস্ত সত্তা এর BaseEntityমতো করে প্রসারিত করবে :
@Entity(name = "Post")
@Table(name = "post")
public class Post extend BaseEntity {
private String title;
@OneToMany(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<PostComment> comments = new ArrayList<>();
@OneToOne(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true,
fetch = FetchType.LAZY
)
private PostDetails details;
@ManyToMany
@JoinTable(
name = "post_tag",
joinColumns = @JoinColumn(
name = "post_id"
),
inverseJoinColumns = @JoinColumn(
name = "tag_id"
)
)
private List<Tag> tags = new ArrayList<>();
//Getters and setters omitted for brevity
}
ব্যবহার সম্পর্কে আরও তথ্যের জন্য @MappedSuperclass, এই নিবন্ধটি দেখুন ।
তবে, এমনকি যদি createdOnএবং updateOnসম্পত্তিগুলি হাইবারনেট-নির্দিষ্ট @CreationTimestampএবং @UpdateTimestampটীকাগুলি দ্বারা সেট করা থাকে , নিম্নলিখিত জেপিএ সমাধান দ্বারা চিত্রিত হিসাবে createdByএবং updatedByঅ্যাপ্লিকেশন কলব্যাকটি নিবন্ধকরণ করার প্রয়োজন হয়।
জেপিএ ব্যবহার করছে @EntityListeners
আপনি একটি এম্বেডেবলে নিরীক্ষণের বৈশিষ্ট্যগুলি encapsulate করতে পারেন:
@Embeddable
public class Audit {
@Column(name = "created_on")
private LocalDateTime createdOn;
@Column(name = "created_by")
private String createdBy;
@Column(name = "updated_on")
private LocalDateTime updatedOn;
@Column(name = "updated_by")
private String updatedBy;
//Getters and setters omitted for brevity
}
এবং, AuditListenerঅডিট বৈশিষ্ট্যগুলি সেট করতে একটি তৈরি করুন :
public class AuditListener {
@PrePersist
public void setCreatedOn(Auditable auditable) {
Audit audit = auditable.getAudit();
if(audit == null) {
audit = new Audit();
auditable.setAudit(audit);
}
audit.setCreatedOn(LocalDateTime.now());
audit.setCreatedBy(LoggedUser.get());
}
@PreUpdate
public void setUpdatedOn(Auditable auditable) {
Audit audit = auditable.getAudit();
audit.setUpdatedOn(LocalDateTime.now());
audit.setUpdatedBy(LoggedUser.get());
}
}
রেজিস্ট্রেশন করতে AuditListener, আপনি @EntityListenersজেপিএ টিকা ব্যবহার করতে পারেন :
@Entity(name = "Post")
@Table(name = "post")
@EntityListeners(AuditListener.class)
public class Post implements Auditable {
@Id
private Long id;
@Embedded
private Audit audit;
private String title;
@OneToMany(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<PostComment> comments = new ArrayList<>();
@OneToOne(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true,
fetch = FetchType.LAZY
)
private PostDetails details;
@ManyToMany
@JoinTable(
name = "post_tag",
joinColumns = @JoinColumn(
name = "post_id"
),
inverseJoinColumns = @JoinColumn(
name = "tag_id"
)
)
private List<Tag> tags = new ArrayList<>();
//Getters and setters omitted for brevity
}
জেপিএর সাথে নিরীক্ষণের বৈশিষ্ট্যগুলি প্রয়োগ করার বিষয়ে আরও তথ্যের জন্য @EntityListener, এই নিবন্ধটি দেখুন ।