jpa
कई से कई मानचित्रण
खोज…
परिचय
एक ManyToMany
मानचित्रण उन संस्थाओं के बीच एक संबंध का वर्णन करता है जहां दोनों एक दूसरे के एक से अधिक उदाहरण से संबंधित हो सकते हैं और @ManyToMany
एनोटेशन द्वारा परिभाषित किया गया है।
@OneToMany
विपरीत, जहां इकाई की तालिका में एक विदेशी कुंजी कॉलम का उपयोग किया जा सकता है, ManyToMany
को एक ManyToMany
तालिका की आवश्यकता होती है, जो संस्थाओं को एक-दूसरे को मैप करती है।
पैरामीटर
टिप्पणी | उद्देश्य |
---|---|
@TableGenerator | एक प्राथमिक कुंजी जनरेटर को परिभाषित करता है जिसे GeneratedValue एनोटेशन के लिए एक जनरेटर तत्व निर्दिष्ट होने पर नाम से संदर्भित किया जा सकता है |
@GeneratedValue | प्राथमिक कुंजी के मूल्यों के लिए पीढ़ी की रणनीतियों के विनिर्देश के लिए प्रदान करता है। यह एक प्राथमिक कुंजी संपत्ति या एक इकाई के क्षेत्र या आईडी एनोटेशन के साथ संयोजन में सुपरक्लास पर लागू किया जा सकता है। |
@ManyToMany | कर्मचारी और परियोजना संस्थाओं के बीच संबंध निर्दिष्ट करता है जैसे कि कई कर्मचारी कई परियोजनाओं पर काम कर सकते हैं। |
mappedBy="projects" | कर्मचारी और परियोजना के बीच एक द्विदिश संबंध को परिभाषित करता है |
@JoinColumn | उस कॉलम का नाम निर्दिष्ट करता है, जो उस संस्था के स्वामी के रूप में मानी जाने वाली इकाई को संदर्भित करेगा |
@JoinTable | डेटाबेस में तालिका निर्दिष्ट करता है जो विदेशी कुंजियों का उपयोग करके संबंधों को प्रोजेक्ट करने के लिए कर्मचारी को रखेगा |
टिप्पणियों
- @TableGenerator और @GeneratedValue का उपयोग जेपा टेबल जनरेटर का उपयोग करके स्वचालित आईडी निर्माण के लिए किया जाता है।
- @ManyToMany एनोटेशन कर्मचारी और प्रोजेक्ट संस्थाओं के बीच संबंध को निर्दिष्ट करता है।
- @JoinTable तालिका का उपयोग करने के लिए तालिका के नाम को निर्दिष्ट करता है क्योंकि कर्मचारी और परियोजना के बीच कई मैपिंग में नाम = "कर्मचारी_प्रोजेक्ट" का उपयोग करते हुए। ऐसा इसलिए किया जाता है क्योंकि कई मैपिंग के लिए एक jpa के स्वामित्व को निर्धारित करने का कोई तरीका नहीं है क्योंकि डेटाबेस टेबल में अन्य तालिका के संदर्भ में विदेशी कुंजी नहीं है।
- @JoinColumn उस कॉलम का नाम निर्दिष्ट करता है, जो इकाई के स्वामी के रूप में मानी जाने वाली इकाई को संदर्भित करेगा, जबकि @inverseJoinColumn, संबंध के व्युत्क्रम का नाम निर्दिष्ट करता है। (आप मालिक के रूप में माने जाने वाले किसी भी पक्ष का चयन कर सकते हैं। बस यह सुनिश्चित कर लें कि रिश्ते में वे पक्ष हैं)। हमारे मामले में हमने कर्मचारी को मालिक के रूप में चुना है, इसलिए @JoinColumn, टेबल कर्मचारी_प्रोजेक्ट में शामिल होने के लिए idemployee कॉलम को संदर्भित करता है और @InverseJoinColumn, idproject को संदर्भित करता है, जो कई मैपिंग के लिए कई jpa के विपरीत होता है।
- प्रोजेक्ट इकाई में @ManyToMany एनोटेशन उलटा संबंध दिखाता है इसलिए यह कर्मचारी इकाई में फ़ील्ड को संदर्भित करने के लिए मैप किए गए प्रोजेक्ट = का उपयोग करता है।
पूरा उदाहरण यहाँ पर दिया जा सकता है
कई मानचित्रण के लिए कई परियोजना के लिए कर्मचारी
कर्मचारी इकाई।
package com.thejavageek.jpa.entities;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.TableGenerator;
@Entity
public class Employee {
@TableGenerator(name = "employee_gen", table = "id_gen", pkColumnName = "gen_name", valueColumnName = "gen_val", allocationSize = 100)
@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "employee_gen")
private int idemployee;
private String name;
@ManyToMany(cascade = CascadeType.PERSIST)
@JoinTable(name = "employee_project", joinColumns = @JoinColumn(name = "idemployee"), inverseJoinColumns = @JoinColumn(name = "idproject"))
private List<Project> projects;
public int getIdemployee() {
return idemployee;
}
public void setIdemployee(int idemployee) {
this.idemployee = idemployee;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Project> getProjects() {
return projects;
}
public void setProjects(List<Project> projects) {
this.projects = projects;
}
}
परियोजना इकाई:
package com.thejavageek.jpa.entities;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.TableGenerator;
@Entity
public class Project {
@TableGenerator(name = "project_gen", allocationSize = 1, pkColumnName = "gen_name", valueColumnName = "gen_val", table = "id_gen")
@Id
@GeneratedValue(generator = "project_gen", strategy = GenerationType.TABLE)
private int idproject;
private String name;
@ManyToMany(mappedBy = "projects", cascade = CascadeType.PERSIST)
private List<Employee> employees;
public int getIdproject() {
return idproject;
}
public void setIdproject(int idproject) {
this.idproject = idproject;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Employee> getEmployees() {
return employees;
}
public void setEmployees(List<Employee> employees) {
this.employees = employees;
}
}
टेस्ट कोड
/ * EntityManagerFactory बनाएँ / * EntityManagerFactory ईएमएफ = दृढ़ता।
/* Create EntityManager */
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin();
Employee prasad = new Employee();
prasad.setName("prasad kharkar");
Employee harish = new Employee();
harish.setName("Harish taware");
Project ceg = new Project();
ceg.setName("CEG");
Project gtt = new Project();
gtt.setName("GTT");
List<Project> projects = new ArrayList<Project>();
projects.add(ceg);
projects.add(gtt);
List<Employee> employees = new ArrayList<Employee>();
employees.add(prasad);
employees.add(harish);
ceg.setEmployees(employees);
gtt.setEmployees(employees);
prasad.setProjects(projects);
harish.setProjects(projects);
em.persist(prasad);
transaction.commit();
एंबेडेबल एनोटेशन के बिना कंपाउंड कुंजी को कैसे संभालना है
यदि आपके पास है
Role:
+-----------------------------+
| roleId | name | discription |
+-----------------------------+
Rights:
+-----------------------------+
| rightId | name | discription|
+-----------------------------+
rightrole
+------------------+
| roleId | rightId |
+------------------+
इसके बाद के संस्करण परिदृश्य में rightrole
तालिका यौगिक कुंजी है और जेपीए उपयोगकर्ता में यह उपयोग करने के लिए के साथ इकाई बनाने के लिए Embeddable
एनोटेशन।
ऐशे ही:
दाएं तालिका के लिए इकाई है:
@Entity
@Table(name = "rightrole")
public class RightRole extends BaseEntity<RightRolePK> {
private static final long serialVersionUID = 1L;
@EmbeddedId
protected RightRolePK rightRolePK;
@JoinColumn(name = "roleID", referencedColumnName = "roleID", insertable = false, updatable = false)
@ManyToOne(fetch = FetchType.LAZY)
private Role role;
@JoinColumn(name = "rightID", referencedColumnName = "rightID", insertable = false, updatable = false)
@ManyToOne(fetch = FetchType.LAZY)
private Right right;
......
}
@Embeddable
public class RightRolePK implements Serializable {
private static final long serialVersionUID = 1L;
@Basic(optional = false)
@NotNull
@Column(nullable = false)
private long roleID;
@Basic(optional = false)
@NotNull
@Column(nullable = false)
private long rightID;
.....
}
एकल ऑब्जेक्ट के लिए एंबेडेबल एनोटेशन ठीक है, लेकिन यह थोक रिकॉर्ड सम्मिलित करते समय एक मुद्दा देगा।
समस्या यह है कि जब भी उपयोगकर्ता rights
साथ नई role
बनाना चाहता है तो पहले उपयोगकर्ता को role
ऑब्जेक्ट को store(persist)
करना होता है और फिर उपयोगकर्ता को रोल के लिए नई जेनरेट की गई id
प्राप्त करने के लिए flush
करना होता है। तब और फिर उपयोगकर्ता इसे rightrole
के ऑब्जेक्ट में डाल सकता है।
इस उपयोगकर्ता को हल करने के लिए इकाई को थोड़ा अलग तरीके से लिख सकते हैं।
भूमिका तालिका के लिए इकाई है:
@Entity
@Table(name = "role")
public class Role {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@NotNull
@Column(nullable = false)
private Long roleID;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "role", fetch = FetchType.LAZY)
private List<RightRole> rightRoleList;
@ManyToMany(cascade = {CascadeType.PERSIST})
@JoinTable(name = "rightrole",
joinColumns = {
@JoinColumn(name = "roleID", referencedColumnName = "ROLE_ID")},
inverseJoinColumns = {
@JoinColumn(name = "rightID", referencedColumnName = "RIGHT_ID")})
private List<Right> rightList;
.......
}
@JoinTable एनोटेशन एक इकाई के बिना भी rightrole
तालिका में सम्मिलित करने का ध्यान rightrole
(जब तक कि तालिका में केवल भूमिका और दाएं का आईडी कॉलम हो)।
उपयोगकर्ता तो बस कर सकते हैं:
Role role = new Role();
List<Right> rightList = new ArrayList<>();
Right right1 = new Right();
Right right2 = new Right();
rightList.add(right1);
rightList.add(right2);
role.setRightList(rightList);
आपको inverseJoinColumns में @ManyToMany (कैस्केड = {CascadeType.PERSIST}) लिखना होगा अन्यथा बच्चे के डिलीट होने पर आपके माता-पिता का डेटा डिलीट हो जाएगा।