आप किस मामले में जेपीए @JoinTable
एनोटेशन का उपयोग करते हैं?
आप किस मामले में जेपीए @JoinTable
एनोटेशन का उपयोग करते हैं?
जवाबों:
EDIT 2017-04-29 : जैसा कि कुछ टिप्पणीकारों ने बताया है, JoinTable
उदाहरण के लिए mappedBy
एनोटेशन विशेषता की आवश्यकता नहीं है । वास्तव में, हाइबरनेट के हाल के संस्करणों ने निम्नलिखित त्रुटि को प्रिंट करने से शुरू करने से इनकार कर दिया:
org.hibernate.AnnotationException:
Associations marked as mappedBy must not define database mappings
like @JoinTable or @JoinColumn
चलो बहाना करते हैं कि आपके पास नाम की एक इकाई है Project
और नाम की एक और इकाई है Task
और प्रत्येक परियोजना में कई कार्य हो सकते हैं।
आप डेटाबेस स्कीमा को दो तरीकों से इस परिदृश्य के लिए डिज़ाइन कर सकते हैं।
पहला समाधान नाम की एक तालिका बनाने के लिए है Project
और दूसरी तालिका नाम की है Task
और कार्य तालिका में एक विदेशी कुंजी कॉलम जोड़ें project_id
:
Project Task
------- ----
id id
name name
project_id
इस तरह, कार्य तालिका में प्रत्येक पंक्ति के लिए परियोजना को निर्धारित करना संभव होगा। यदि आप अपनी इकाई कक्षाओं में इस दृष्टिकोण का उपयोग करते हैं, तो आपको ज्वाइन टेबल की आवश्यकता नहीं होगी:
@Entity
public class Project {
@OneToMany(mappedBy = "project")
private Collection<Task> tasks;
}
@Entity
public class Task {
@ManyToOne
private Project project;
}
अन्य समाधान तीसरी तालिका का उपयोग करना है, उदाहरण के लिए Project_Tasks
, और उस तालिका में परियोजनाओं और कार्यों के बीच संबंधों को संग्रहीत करना है:
Project Task Project_Tasks
------- ---- -------------
id id project_id
name name task_id
Project_Tasks
तालिका एक "में शामिल होने तालिका" कहा जाता है। जेपीए में इस दूसरे समाधान को लागू करने के लिए आपको @JoinTable
एनोटेशन का उपयोग करने की आवश्यकता है । उदाहरण के लिए, एक-दिशात्मक एक से कई एसोसिएशन को लागू करने के लिए, हम अपनी संस्थाओं को इस तरह परिभाषित कर सकते हैं:
Project
इकाई:
@Entity
public class Project {
@Id
@GeneratedValue
private Long pid;
private String name;
@JoinTable
@OneToMany
private List<Task> tasks;
public Long getPid() {
return pid;
}
public void setPid(Long pid) {
this.pid = pid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Task> getTasks() {
return tasks;
}
public void setTasks(List<Task> tasks) {
this.tasks = tasks;
}
}
Task
इकाई:
@Entity
public class Task {
@Id
@GeneratedValue
private Long tid;
private String name;
public Long getTid() {
return tid;
}
public void setTid(Long tid) {
this.tid = tid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
यह निम्नलिखित डेटाबेस संरचना बनाएगा:
@JoinTable
एनोटेशन भी आप तालिका में शामिल होने के विभिन्न पहलुओं को अनुकूलित करने देता। उदाहरण के लिए, क्या हमने tasks
संपत्ति को इस तरह से एनोटेट किया था :
@JoinTable(
name = "MY_JT",
joinColumns = @JoinColumn(
name = "PROJ_ID",
referencedColumnName = "PID"
),
inverseJoinColumns = @JoinColumn(
name = "TASK_ID",
referencedColumnName = "TID"
)
)
@OneToMany
private List<Task> tasks;
परिणामस्वरूप डेटाबेस बन जाएगा:
अंत में, यदि आप कई-से-कई एसोसिएशन के लिए एक स्कीमा बनाना चाहते हैं, तो ज्वाइन टेबल का उपयोग करना एकमात्र उपलब्ध समाधान है।
@JoinTable/@JoinColumn
उसी क्षेत्र के साथ एनोटेट किया जा सकता है mappedBy
। तो सही उदाहरण रखते हुए किया जाना चाहिए mappedBy
में Project
, और ले जाने के @JoinColumn
लिए Task.project
(या इसके विपरीत)
Project_Tasks
की जरूरत है name
की Task
जो तीन कॉलम हो जाता है और साथ ही,: project_id
, task_id
, task_name
, कैसे इस लक्ष्य को हासिल करने के लिए?
Caused by: org.hibernate.AnnotationException: Associations marked as mappedBy must not define database mappings like @JoinTable or @JoinColumn:
यह भी उपयोग करने के लिए क्लीनर है @JoinTable
जब कई माता-पिता / विभिन्न प्रकार के माता-पिता के साथ बच्चे के संबंधों में एक इकाई बच्चा हो सकता है। Behrang के उदाहरण के साथ पालन करने के लिए, एक कार्य की कल्पना करें परियोजना, व्यक्ति, विभाग, अध्ययन और प्रक्रिया का बच्चा हो सकता है।
क्या task
तालिका में 5 nullable
विदेशी कुंजी फ़ील्ड होनी चाहिए ? मुझे नहीं लगता...
यह एक ManyToMany एसोसिएशन को मैप करने का एकमात्र समाधान है: आपको एसोसिएशन मैप करने के लिए दो एंटिटी टेबल के बीच एक ज्वाइन टेबल चाहिए।
यह OneToMany (आमतौर पर यूनिडायरेक्शनल) संघों के लिए भी उपयोग किया जाता है जब आप कई पक्ष की तालिका में एक विदेशी कुंजी नहीं जोड़ना चाहते हैं और इस तरह इसे एक तरफ से स्वतंत्र रखते हैं।
स्पष्टीकरण और उदाहरण के लिए हाइबरनेट प्रलेखन में @JoinTable के लिए खोजें ।
यह आपको कई से कई संबंधों को संभालने देता है। उदाहरण:
Table 1: post
post has following columns
____________________
| ID | DATE |
|_________|_________|
| | |
|_________|_________|
Table 2: user
user has the following columns:
____________________
| ID |NAME |
|_________|_________|
| | |
|_________|_________|
तालिका में शामिल होने से आप मानचित्रण का उपयोग कर सकते हैं:
@JoinTable(
name="USER_POST",
joinColumns=@JoinColumn(name="USER_ID", referencedColumnName="ID"),
inverseJoinColumns=@JoinColumn(name="POST_ID", referencedColumnName="ID"))
एक तालिका बनाएंगे:
____________________
| USER_ID| POST_ID |
|_________|_________|
| | |
|_________|_________|
@ManyToMany
संघोंसबसे अधिक बार, आपको @JoinTable
कई-कई तालिका संबंधों की मैपिंग को निर्दिष्ट करने के लिए एनोटेशन का उपयोग करने की आवश्यकता होगी :
तो, मान लें कि आपके पास निम्नलिखित डेटाबेस टेबल हैं:
में Post
इकाई, तो आप इस संबंध है, इस तरह के नक्शे होगा:
@ManyToMany(cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
})
@JoinTable(
name = "post_tag",
joinColumns = @JoinColumn(name = "post_id"),
inverseJoinColumns = @JoinColumn(name = "tag_id")
)
private List<Tag> tags = new ArrayList<>();
@JoinTable
टिप्पणी द्वारा तालिका नाम निर्दिष्ट करने के लिए प्रयोग किया जाता है name
विशेषता है, साथ ही विदेशी कुंजी स्तंभ संदर्भ post
तालिका (जैसे, joinColumns
) और में विदेशी कुंजी स्तंभ post_tag
लिंक तालिका संदर्भ Tag
के माध्यम से इकाई inverseJoinColumns
विशेषता।
ध्यान दें कि
@ManyToMany
एनोटेशन की कैस्केड विशेषता केवलPERSIST
औरMERGE
केवल इसलिए सेट की जाती है क्योंकि कैस्केडिंगREMOVE
एक बुरा विचार है क्योंकि हम DELETE स्टेटमेंट को अन्य पैरेंट रिकॉर्ड के लिए जारी किया जाएगा,tag
हमारे मामले में रिकॉर्ड में नहींpost_tag
। इस विषय के बारे में अधिक जानकारी के लिए, इस लेख को देखें ।
@OneToMany
संघयूनिडायरेक्शनल @OneToMany
एसोसिएशन, जिसमें एक @JoinColumn
मैपिंग की कमी है , एक -से-कई के बजाय कई-टू-टेबल संबंधों की तरह व्यवहार करते हैं।
तो, मान लें कि आपके पास निम्नलिखित इकाई मैपिंग हैं:
@Entity(name = "Post")
@Table(name = "post")
public class Post {
@Id
@GeneratedValue
private Long id;
private String title;
@OneToMany(
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<PostComment> comments = new ArrayList<>();
//Constructors, getters and setters removed for brevity
}
@Entity(name = "PostComment")
@Table(name = "post_comment")
public class PostComment {
@Id
@GeneratedValue
private Long id;
private String review;
//Constructors, getters and setters removed for brevity
}
हाइबरनेट उपरोक्त निकाय मानचित्रण के लिए निम्नलिखित डेटाबेस स्कीमा ग्रहण करेगा:
जैसा कि पहले ही समझाया गया है, यूनिडायरेक्शनल @OneToMany
जेपीए मैपिंग कई-से-कई एसोसिएशन की तरह व्यवहार करता है।
लिंक तालिका को अनुकूलित करने के लिए, आप @JoinTable
एनोटेशन का भी उपयोग कर सकते हैं :
@OneToMany(
cascade = CascadeType.ALL,
orphanRemoval = true
)
@JoinTable(
name = "post_comment_ref",
joinColumns = @JoinColumn(name = "post_id"),
inverseJoinColumns = @JoinColumn(name = "post_comment_id")
)
private List<PostComment> comments = new ArrayList<>();
और अब, लिंक तालिका के नाम से जाना जा रहा है post_comment_ref
और विदेशी कुंजी स्तंभ हो जाएगा post_id
के लिए, post
मेज, और post_comment_id
के लिए, post_comment
तालिका।
यूनिडायरेक्शनल
@OneToMany
एसोसिएशन कुशल नहीं हैं, इसलिए आप द्विदिश@OneToMany
संघों या सिर्फ@ManyToOne
पक्ष का उपयोग कर बेहतर हैं । की जाँच करें इस लेख में इस विषय के बारे में अधिक जानकारी के लिए।