কোন ক্ষেত্রে আপনি জেপিএ @JoinTableটিকা ব্যবহার করেন ?
কোন ক্ষেত্রে আপনি জেপিএ @JoinTableটিকা ব্যবহার করেন ?
উত্তর:
সম্পাদনা 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 বিভিন্ন ধরণের পিতামাতার সাথে একাধিক পিতা-মাতার / সন্তানের সম্পর্কের যখন কোনও সত্তা শিশু হতে পারে তখন । বেহরংয়ের উদাহরণ অনুসরণ করতে, কল্পনা করুন যে কোনও টাস্ক প্রকল্প, ব্যক্তি, বিভাগ, স্টাডি এবং প্রক্রিয়াটির শিশু হতে পারে।
করা উচিত taskটেবিল 5 আছে nullableবিদেশী কী ক্ষেত্র? আমি মনে করি না...
ম্যান্টিটোম্যান অ্যাসোসিয়েশন ম্যাপ করার এটিই একমাত্র সমাধান: অ্যাসোসিয়েশন ম্যাপ করার জন্য আপনার দুটি সত্তার টেবিলের মধ্যে একটি টেবিলের প্রয়োজন।
এটি যখন আপনি অনেক দিকের টেবিলের মধ্যে কোনও বিদেশী কী যুক্ত করতে চান না এবং এভাবে একে একপাশে আলাদা রাখতে চান না তখন এটি ওয়ানটোম্যানির (সাধারণত একমুখী) সংঘের জন্যও ব্যবহৃত হয়।
ব্যাখ্যা এবং উদাহরণগুলির জন্য হাইপারনেট ডকুমেন্টেশনে @ জয়েন্ট টেবিল অনুসন্ধান করুন ।
এটি আপনাকে অনেকের সাথে অনেকের সম্পর্ককে পরিচালনা করতে দেয়। উদাহরণ:
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একটি খারাপ ধারণা কারণ আমরা মুছে ফেলা বিবৃতি অন্য পিতামাতার রেকর্ডের জন্য জারি করা হবে,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পাশ। পরীক্ষা করে দেখুন এই নিবন্ধটি এই বিষয় সম্পর্কে আরো বিস্তারিত জানার জন্য।