কোন ক্ষেত্রে আপনি জেপিএ @ জোইনটেবল টিকাটি ব্যবহার করেন?


উত্তর:


350

সম্পাদনা 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;

ফলাফল ডাটাবেস হয়ে যেত:

ইআর ডায়াগ্রাম 2

অবশেষে, আপনি যদি বহু-বহু-সংস্থার জন্য একটি স্কিমা তৈরি করতে চান তবে একটি জয়েন টেবিল ব্যবহার করা একমাত্র উপলভ্য সমাধান।


1
প্রথম প্রকল্পটি ব্যবহার করে আমি আমার প্রকল্পটি আমার কাজগুলিতে পূর্ণ করেছি এবং একত্রীকরণের পূর্বে প্রতিটি কার্যকেন্দ্রিক প্রকল্পে পূর্ণ হয় এবং কাজ করে তবে আমার সমস্ত এন্ট্রিগুলি আমার কাজের সংখ্যার ভিত্তিতে সদৃশ হয়। দুটি ডাটা সহ একটি প্রকল্প আমার ডেটাবেজে দু'বার সংরক্ষণ করা হয়েছে। কেন?
মাইকোআইডি

আপডেট করুন আমার ডাটাবেসে সদৃশ এন্ট্রি নেই, হাইবারনেট বাম বাহিরের
জোড়

2
আমি বিশ্বাস করি এর @JoinTable/@JoinColumnসাথে একই মাঠে মন্তব্য করা যেতে পারে mappedBy। তাই সঠিক উদাহরণস্বরূপ পালন করা উচিত mappedByমধ্যে Project, এবং সরানো @JoinColumnকরতে Task.project (অথবা বিপরীতভাবে)
আদ্রিয়ান Shum

2
নিস! কিন্তু আমি আরও প্রশ্ন আছে: যদি যোগ দিতে টেবিল Project_Tasksদরকার nameএর Taskযা তিন কলাম হয়ে পাশাপাশি: project_id, task_id, task_name, কিভাবে এই অর্জন কিভাবে?
macemers

5
আমার মনে হয় আপনি এই ত্রুটি প্রতিরোধ আপনার দ্বিতীয় ব্যবহারের উদাহরণ mappedBy থাকা উচিত নয়Caused by: org.hibernate.AnnotationException: Associations marked as mappedBy must not define database mappings like @JoinTable or @JoinColumn:
কার্তিক মি

14

এটি ব্যবহার করাও ক্লিনার @JoinTable বিভিন্ন ধরণের পিতামাতার সাথে একাধিক পিতা-মাতার / সন্তানের সম্পর্কের যখন কোনও সত্তা শিশু হতে পারে তখন । বেহরংয়ের উদাহরণ অনুসরণ করতে, কল্পনা করুন যে কোনও টাস্ক প্রকল্প, ব্যক্তি, বিভাগ, স্টাডি এবং প্রক্রিয়াটির শিশু হতে পারে।

করা উচিত taskটেবিল 5 আছে nullableবিদেশী কী ক্ষেত্র? আমি মনে করি না...


14

ম্যান্টিটোম্যান অ্যাসোসিয়েশন ম্যাপ করার এটিই একমাত্র সমাধান: অ্যাসোসিয়েশন ম্যাপ করার জন্য আপনার দুটি সত্তার টেবিলের মধ্যে একটি টেবিলের প্রয়োজন।

এটি যখন আপনি অনেক দিকের টেবিলের মধ্যে কোনও বিদেশী কী যুক্ত করতে চান না এবং এভাবে একে একপাশে আলাদা রাখতে চান না তখন এটি ওয়ানটোম্যানির (সাধারণত একমুখী) সংঘের জন্যও ব্যবহৃত হয়।

ব্যাখ্যা এবং উদাহরণগুলির জন্য হাইপারনেট ডকুমেন্টেশনে @ জয়েন্ট টেবিল অনুসন্ধান করুন ।


4

এটি আপনাকে অনেকের সাথে অনেকের সম্পর্ককে পরিচালনা করতে দেয়। উদাহরণ:

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 |
|_________|_________|
|         |         |
|_________|_________|

1
প্রশ্ন: আমার যদি ইতিমধ্যে এই অতিরিক্ত টেবিলটি থাকে? জয়েন্ট টেবিলটি কি অস্তিত্বের উপরের লিখনের উপর নির্ভর করতে পারে?
দ্য ওয়ান্ডারার

@ দ্য ওয়ার্ডারার আপনার প্রশ্নের উত্তর খুঁজে পেয়েছেন? আমার কাছে ইতিমধ্যে একটি যোগদানের টেবিল রয়েছে

আমার ক্ষেত্রে এটি নিজস্ব পাশের টেবিলে একটি অপ্রয়োজনীয় কলাম তৈরি করছে। যেমন। POST এ POST_ID। আপনি কি বলতে পারেন যে এটি কেন হচ্ছে?
এসপিএস

0

@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পাশ। পরীক্ষা করে দেখুন এই নিবন্ধটি এই বিষয় সম্পর্কে আরো বিস্তারিত জানার জন্য।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.