मैं कुछ समय के लिए जेपीए (कार्यान्वयन हाइबरनेट) के साथ काम कर रहा हूं और हर बार मुझे ऐसी इकाइयां बनाने की आवश्यकता होती है, जो मुझे खुद को एक्सेसटेप, अपरिवर्तनीय गुणों, बराबर / हैशकोड, ... जैसे मुद्दों से जूझना पड़ता है।
इसलिए मैंने प्रत्येक मुद्दे के लिए सामान्य सर्वोत्तम अभ्यास का पता लगाने का प्रयास किया और इसे व्यक्तिगत उपयोग के लिए लिख दिया।
हालांकि किसी के लिए इस पर टिप्पणी करना या मुझे यह बताना गलत नहीं होगा कि मैं कहां गलत हूं।
इकाई वर्ग
लागू करने योग्य
कारण: विनिर्देश आपको कहते हैं, लेकिन कुछ जेपीए प्रदाता इसे लागू नहीं करते हैं। JPA प्रदाता के रूप में हाइबरनेट यह लागू नहीं करता है, लेकिन यह ClassCastException के साथ इसके पेट में कहीं गहरे विफल हो सकता है, अगर Serializable कार्यान्वित नहीं किया गया है।
कंस्ट्रक्टर्स
इकाई के सभी आवश्यक क्षेत्रों के साथ एक निर्माता बनाएँ
कारण: एक कंस्ट्रक्टर को हमेशा एक बने हुए अवस्था में छोड़ना चाहिए।
इस कंस्ट्रक्टर के अलावा: एक पैकेज निजी डिफ़ॉल्ट कंस्ट्रक्टर है
कारण: डिफ़ॉल्ट कंस्ट्रक्टर को इकाई को इनिशियलाइज़ करने के लिए आवश्यक है; निजी की अनुमति है लेकिन पैकेज निजी (या सार्वजनिक) दृश्यता के लिए आवश्यक है रनटाइम प्रॉक्सी पीढ़ी और कुशल डेटा पुनर्प्राप्ति के लिए बायटेकोड इंस्ट्रूमेंटेशन के बिना।
फील्ड्स / गुण
जरूरत पड़ने पर सामान्य और संपत्ति के उपयोग में फील्ड एक्सेस का उपयोग करें
कारण: यह संभवतः सबसे अधिक विवादित मुद्दा है क्योंकि एक या दूसरे के लिए कोई स्पष्ट और ठोस तर्क नहीं हैं (संपत्ति का उपयोग बनाम फ़ील्ड एक्सेस); हालाँकि, फ़ील्ड का उपयोग स्पष्ट कोड, बेहतर एनकैप्सुलेशन और अपरिवर्तनीय क्षेत्रों के लिए बसने की आवश्यकता के कारण सामान्य पसंदीदा नहीं लगता है
ओमिट अपरिवर्तनीय क्षेत्रों के लिए बसता है (एक्सेस प्रकार फ़ील्ड के लिए आवश्यक नहीं)
- निजी
कारण हो सकते हैं कारण: मैंने एक बार सुना है कि संरक्षित (हाइबरनेट) प्रदर्शन के लिए बेहतर है, लेकिन मुझे वेब पर सभी मिल सकते हैं: हाइबरनेट सार्वजनिक, निजी और संरक्षित एक्सेसर विधियों के साथ-साथ सार्वजनिक, निजी और संरक्षित क्षेत्रों तक पहुंच बना सकता है। । चुनाव आप पर निर्भर है और आप इसे अपने आवेदन डिजाइन के अनुरूप कर सकते हैं।
बराबर है / hashCode
- यदि यह आईडी केवल इकाई को बनाए रखने के समय सेट की गई हो तो कभी भी उत्पन्न आईडी का उपयोग न करें
- वरीयता द्वारा: एक अद्वितीय व्यवसाय कुंजी बनाने के लिए अपरिवर्तनीय मूल्यों का उपयोग करें और समानता का परीक्षण करने के लिए इसका उपयोग करें
- यदि कोई विशिष्ट व्यवसाय कुंजी उपलब्ध नहीं है, तो एक गैर-क्षणिक UUID का उपयोग करें, जो तब बनाया जाता है जब इकाई आरंभ होती है; देखें इस महान लेख और जानकारी के लिए।
- संबंधित संस्थाओं (ManyToOne) को कभी न देखें; यदि इस संस्था (एक मूल इकाई की तरह) को बिजनेस की का हिस्सा बनना है तो केवल आईडी की तुलना करें। जब तक आप प्रॉपर्टी ऐक्सेस टाइप का उपयोग कर रहे हों, तब तक प्रॉक्सी पर कॉलिंग गेटआईड () को लोडिंग इकाई को ट्रिगर नहीं करेगा ।
उदाहरण इकाई
@Entity
@Table(name = "ROOM")
public class Room implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
@Column(name = "room_id")
private Integer id;
@Column(name = "number")
private String number; //immutable
@Column(name = "capacity")
private Integer capacity;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "building_id")
private Building building; //immutable
Room() {
// default constructor
}
public Room(Building building, String number) {
// constructor with required field
notNull(building, "Method called with null parameter (application)");
notNull(number, "Method called with null parameter (name)");
this.building = building;
this.number = number;
}
@Override
public boolean equals(final Object otherObj) {
if ((otherObj == null) || !(otherObj instanceof Room)) {
return false;
}
// a room can be uniquely identified by it's number and the building it belongs to; normally I would use a UUID in any case but this is just to illustrate the usage of getId()
final Room other = (Room) otherObj;
return new EqualsBuilder().append(getNumber(), other.getNumber())
.append(getBuilding().getId(), other.getBuilding().getId())
.isEquals();
//this assumes that Building.id is annotated with @Access(value = AccessType.PROPERTY)
}
public Building getBuilding() {
return building;
}
public Integer getId() {
return id;
}
public String getNumber() {
return number;
}
@Override
public int hashCode() {
return new HashCodeBuilder().append(getNumber()).append(getBuilding().getId()).toHashCode();
}
public void setCapacity(Integer capacity) {
this.capacity = capacity;
}
//no setters for number, building nor id
}
इस सूची में जोड़ने के अन्य सुझाव स्वागत से अधिक हैं ...
अपडेट करें
इस लेख को पढ़ने के बाद से मैंने eq / hC को लागू करने के अपने तरीके को अनुकूलित किया है:
- यदि कोई अपरिवर्तनीय सरल व्यवसाय कुंजी उपलब्ध है: इसका उपयोग करें
- अन्य सभी मामलों में: एक uuid का उपयोग करें
final
(आपके बसने की ललक को देखते हुए, मुझे लगता है कि आप भी ऐसा करेंगे)।
notNull
से आता है?