1. आपको किस डेटाबेस कॉलम का उपयोग करना चाहिए
आपका पहला सवाल था:
डेटाबेस में आप किस प्रकार के डेटा का उपयोग करेंगे (MySQL मानते हुए, संभवत: एक अलग टाइमज़ोन कि JVM में)? क्या डेटा के प्रकार टाइमजोन-जागरूक होंगे?
MySQL में, TIMESTAMPकॉलम प्रकार JDBC ड्राइवर स्थानीय समय क्षेत्र से डेटाबेस टाइमज़ोन पर शिफ्टिंग करता है, लेकिन यह केवल टाइमस्टैम्प को स्टोर कर सकता है '2038-01-19 03:14:07.999999, इसलिए यह भविष्य के लिए सबसे अच्छा विकल्प नहीं है।
इसलिए, DATETIMEइसके बजाय बेहतर उपयोग , जिसमें यह ऊपरी सीमा सीमा नहीं है। हालांकि, DATETIMEटाइमजोन जागरूक नहीं है। तो, इस कारण से, डेटाबेस की ओर से यूटीसी का उपयोग करना और hibernate.jdbc.time_zoneहाइबरनेट संपत्ति का उपयोग करना सबसे अच्छा है ।
hibernate.jdbc.time_zoneसेटिंग के बारे में अधिक जानकारी के लिए , इस लेख को देखें ।
2. आपको किस इकाई की संपत्ति का उपयोग करना चाहिए
आपका दूसरा प्रश्न था:
आप जावा (दिनांक, कैलेंडर, दीर्घ, ...) में किस प्रकार के डेटा का उपयोग करेंगे?
जावा पक्ष पर, आप जावा 8 का उपयोग कर सकते हैं LocalDateTime। आप विरासत का उपयोग भी कर सकते हैं Date, लेकिन जावा 8 दिनांक / समय प्रकार बेहतर हैं क्योंकि वे अपरिवर्तनीय हैं, और उन्हें लॉग करते समय स्थानीय समय क्षेत्र में शिफ्ट करने के लिए टाइमज़ोन नहीं करते हैं।
हाइबरनेट द्वारा समर्थित जावा 8 दिनांक / समय प्रकार के बारे में अधिक जानकारी के लिए, इस लेख को देखें ।
अब, हम इस प्रश्न का उत्तर भी दे सकते हैं:
मैपिंग के लिए आप किस एनोटेशन का उपयोग करेंगे (जैसे @Temporal)?
यदि आप टाइमस्टैम्प इकाई संपत्ति का उपयोग कर रहे हैं LocalDateTimeया java.sql.Timestampमैप करने के लिए उपयोग कर रहे हैं, तो आपको उपयोग करने की आवश्यकता नहीं है @Temporalक्योंकि HIbernate को पहले से ही पता है कि इस संपत्ति को JDBC टाइमस्टैम्प के रूप में सहेजा जाना है।
केवल यदि आप उपयोग कर रहे हैं java.util.Date, तो आपको @Temporalएनोटेशन निर्दिष्ट करने की आवश्यकता है , जैसे:
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "created_on")
private Date createdOn;
लेकिन, अगर आप इसे इस तरह से मैप करते हैं तो यह बहुत बेहतर है:
@Column(name = "created_on")
private LocalDateTime createdOn;
ऑडिट कॉलम मान कैसे उत्पन्न करें
आपका तीसरा प्रश्न था:
आप टाइमस्टैम्प-डेटाबेस, ओआरएम फ्रेमवर्क (हाइबरनेट), या एप्लिकेशन प्रोग्रामर को स्थापित करने के लिए किसे जिम्मेदार ठहराएंगे?
मैपिंग के लिए आप किस एनोटेशन का उपयोग करेंगे (उदाहरण @Temporal)?
इस लक्ष्य को प्राप्त करने के कई तरीके हैं। आप डेटाबेस को ऐसा करने की अनुमति दे सकते हैं।
के लिए create_onस्तंभ, आप एक इस्तेमाल कर सकते हैं DEFAULTजैसे DDL बाधा,:
ALTER TABLE post
ADD CONSTRAINT created_on_default
DEFAULT CURRENT_TIMESTAMP() FOR created_on;
के लिए updated_onस्तंभ, आप एक डीबी ट्रिगर का उपयोग स्तंभ मान के साथ स्थापित करने के लिए कर सकता है CURRENT_TIMESTAMP()हर बार किसी पंक्ति संशोधित किया गया है।
या, उन्हें सेट करने के लिए JPA या हाइबरनेट का उपयोग करें।
मान लें कि आपके पास निम्नलिखित डेटाबेस टेबल हैं:

और, प्रत्येक तालिका में कॉलम हैं:
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
आप ऑडिट गुणों को एक एंबेडेबल में इनकैप्सुलेट कर सकते हैं:
@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, आप @EntityListenersJPA एनोटेशन का उपयोग कर सकते हैं :
@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, इस लेख को देखें ।