我的应用程序中有一个 Question 实体和一个 QuestionCategory 实体。在数据库中,这是一个多对多的关系。我可能需要一些帮助。
我应该在引用 QuestionCategory 和 visa verca 的问题中创建列表引用吗?然后 JPA 可以根据您从哪个实体开始自动获取类别或问题。
或者您是否应该在它们之间没有引用,然后使用 JPQL 作为命名查询来检索属于该类别的问题,或者根据您所追求的问题检索属于这些问题的类别?
我不知道我是否使用了很多引用。你如何决定这个?
我的应用程序中有一个 Question 实体和一个 QuestionCategory 实体。在数据库中,这是一个多对多的关系。我可能需要一些帮助。
我应该在引用 QuestionCategory 和 visa verca 的问题中创建列表引用吗?然后 JPA 可以根据您从哪个实体开始自动获取类别或问题。
或者您是否应该在它们之间没有引用,然后使用 JPQL 作为命名查询来检索属于该类别的问题,或者根据您所追求的问题检索属于这些问题的类别?
我不知道我是否使用了很多引用。你如何决定这个?
中没有Bidirectional
关系ManyToMany
。主要的事情是注意使用CascadeType
. 根据您的CascadeType
类型使用情况,可能会出现不必要的问题。在我的例子中,Manager
和Project
是ManyToMay
关系。
例子 :
管理器.java
@Entity
public class Manager implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@ManyToMany(mappedBy = "managers", cascade = CascadeType.REFRESH)
private List<Project> projects;
public Manager() {
projects = new ArrayList<Project>();
}
public Manager(String name) {
this.name = name;
projects = new ArrayList<Project>();
}
//getter and setter
public void add(Project project) {
if (!projects.contains(project)) {
projects.add(project);
}
if (!project.getManagers().contains(this)) {
project.getManagers().add(this);
}
}
}
项目.java
@Entity
public class Project implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@ManyToMany
@JoinTable(name = "PROJ_DEP", joinColumns = @JoinColumn(name = "PROJ_ID"), inverseJoinColumns = @JoinColumn(name = "DEPT_ID"))
private List<Manager> managers;
public Project() {
managers = new ArrayList<Manager>();
}
public Project(String name) {
this.name = name;
managers = new ArrayList<Manager>();
}
//getter and setter
public void add(Manager manager) {
if (!managers.contains(manager)) {
managers.add(manager);
}
if (!manager.getProjects().contains(this)) {
manager.getProjects().add(this);
}
}
}
多对多测试.java
public class ManyToManyTest {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("JPA");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Project p1 = new Project("Project 1");
Project p2 = new Project("Project 2");
Project p3 = new Project("Project 3");
Manager m1 = new Manager("Jon");
m1.add(p1);
m1.add(p2);
m1.add(p3);
Manager m2 = new Manager("Kone");
m2.add(p2);
m2.add(p3);
em.persist(m1);
em.persist(m2);
System.out.println("Success..");
em.getTransaction().commit();
em.close();
}
}
假设CascadeType.REMOVE
或CascadeType.ALL
包含在Manager
实体中。
在这里,问题是没有m2的项目记录。
/*Kone's projects record will be loss.*/
Manager m = (Manager)em.createQuery("SELECT m FROM Manager m WHERE m.name = 'Jon' ").getSingleResult();
em.remove(m);
假设CascadeType.PERSIST
或CascadeType.ALL
包含在Manager
实体中。
Manager
,它的项目可能是新的和现有的记录。Project
将是新的记录。Project
(By query)的现有实例将被引用。
/*When m3 has persisted, p2 will be new record in Project table. p1 will be just reference.*/
Project p1 = (Project)em.createQuery("SELECT m FROM Project m WHERE m.name = 'Project 1' ").getSingleResult();
Project p2 = new Project("Project 1");
Manager m3 = new Manager("Nexz");
em.persist(m3);
我的建议是使用CascadeType.REFRESH
,无论您创建什么Manager
或Project
引用都将通过查询从数据库中检索。
JPA 提供者确实支持多对多关系。因此,您可以按您提到的那样放置列表并用适当的 ManyToMany 注释标记它并加入列名,JAP 将为您完成剩下的工作。顺便说一句,您拥有哪个 JPA 提供商???像hibernate,IBatis等??
代码示例:http ://www.roseindia.net/jpa/eclipsejpaexamples/jparelationship/many-to-many.shtml