我的申请中有一个Question实体和一个QuestionCategory实体。在数据库中,这是一种多对多的关系。我可能需要一些帮助。
我应该在引用QuestionCategory和visa verca的问题中创建一个List引用吗?然后,JPA可以根据您开始使用的实体自动获取类别或问题。
或者,您是否应该在它们之间有引用,然后使用JPQL作为命名查询,而不是根据您所追求的内容检索属于该类别的问题或属于问题的类别?
我不知道我是否使用了很多参考文献。你怎么决定这个?
答案 0 :(得分:0)
JPA提供商确实支持多对多关系。所以你可以按照你提到的那样列出&用适当的ManyToMany注释和标记来标记它加入专栏名称& JAP将为您完成剩余的工作。 BTW哪个JPA提供商你有???像hibernate,IBatis等?
代码示例:http://www.roseindia.net/jpa/eclipsejpaexamples/jparelationship/many-to-many.shtml
答案 1 :(得分:0)
Bidirectional
中没有ManyToMany
关系。主要的是要注意CascadeType
的使用。
根据您的CascadeType
类型用法,可能会出现不必要的问题。在我的示例中,Manager
和Project
是ManyToMay
关系。
示例:
Manager.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);
}
}
}
Project.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);
}
}
}
ManyToManyTest.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
(按查询)的现有实例将被引用。
/*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
,都会通过查询从数据库中检索引用。