JPA 和 Hibernate 保持@manytoOne 关系
JPA and Hibernate persisting @manytoOne relationship
我遇到这种情况:
@Entity
@Table(name = "project_leader")
public class ProjectLeader {
@ManyToOne
@JoinColumn(name = "projectId")
@JsonBackReference(value = "project")
private Project project;
...
和相关实体
@Entity
@Table(name = "project")
public class Project {
@OneToMany(fetch = FetchType.EAGER, mappedBy = "project", orphanRemoval = true)
@Cascade(CascadeType.ALL)
@JsonManagedReference(value = "project")
private Set<ProjectLeader> projectLeaders = new HashSet<ProjectLeader>();
例如情况
Project_A 与 ProjectLeader_1 和
Project_B 和 ProjectLeader_2
当我尝试将 ProjectLeader_1 添加到 Project_B 时,我也得到 ProjectLeader_1 从 Project_A 完全移动到 Project_B,所以我有以下内容情况:
Project_A with -No leader- and
Project_B 与 ProjectLeader_2 ProjectLeader_1
理想的结果应该是:
Project_A 与 ProjectLeader_1 和
Project_B 与 ProjectLeader_2 ProjectLeader_1
项目负责人分配方法如下:
private Project initializeProject(@Nonnull ProjectDto projectDto) {
Project project = null;
if (projectDto.getId() != null) {
project = projectRepository.findOne(projectDto.getId());
} else {
project = new Project();
}
project.setName(projectDto.getName());
project.setProjectType(projectDto.getProjectType());
project.setFinancedBy(projectDto.getFinancedBy());
Set<ProjectLeader> projectLeaders = new HashSet<ProjectLeader>();
for (ProjectLeaderDto projectLeaderDto : projectDto.getProjectLeaderDtos()) {
ProjectLeader projectLeader = new ProjectLeader();
Professor professor = null;
if (projectLeaderDto.getId() != null && projectLeaderDto.getId() > 0L) {
projectLeader = projectLeaderRepository.findOne(projectLeaderDto.getId());
}
if (projectLeaderDto.getProfessorId() != null && projectLeaderDto.getProfessorId() > 0L) {
professor = professorRepository.findOne(projectLeaderDto.getProfessorId());
}
projectLeader.setName(projectLeaderDto.getName());
projectLeader.setSurname(projectLeaderDto.getSurname());
projectLeader.setProject(project);
projectLeader.setProfessor(professor);
projectLeaders.add(projectLeader);
}
// If collection from Dto miss some element from original collection, we
// remove it from original
Iterator<ProjectLeader> currentLeadersIterator = project.getProjectLeaders().iterator();
while (currentLeadersIterator.hasNext()) {
ProjectLeader projectLeader = currentLeadersIterator.next();
if (!projectLeaders.contains(projectLeader)) {
currentLeadersIterator.remove();
projectLeader.setProject(null);
}
}
// If original collection miss some element from Dto collection, we add
// it to original
Iterator<ProjectLeader> newLeadersIterator = projectLeaders.iterator();
while (newLeadersIterator.hasNext()) {
ProjectLeader projectLeader = newLeadersIterator.next();
if (!project.getProjectLeaders().contains(projectLeader)) {
project.getProjectLeaders().add(projectLeader);
projectLeader.setProject(project);
}
}
return project;
}
这可能是什么原因?
我是新来的所以请 post 我 link 如果其他地方有类似的问题。
谢谢。
我认为插入有问题,请注意每个项目都有一个项目负责人,所以如果你把另一个负责人放到项目中,旧的会被删除,新的会插入,我写了一个小程序关于你的问题:
package leader;
import java.io.Serializable;
import javax.persistence.*;
/**
* The persistent class for the Project database table.
*
*/
@Entity
@NamedQuery(name="Project.findAll", query="SELECT p FROM Project p")
public class Project implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private int id;
//bi-directional many-to-one association to ProjectLeader
@ManyToOne
@JoinColumn(name="Leader_Id")
private ProjectLeader projectLeader;
public Project() {
}
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public ProjectLeader getProjectLeader() {
return this.projectLeader;
}
public void setProjectLeader(ProjectLeader projectLeader) {
this.projectLeader = projectLeader;
}
}
项目负责人class:
package leader;
import java.io.Serializable;
import javax.persistence.*;
import java.util.List;
@Entity
@NamedQuery(name="ProjectLeader.findAll", query="SELECT p FROM ProjectLeader p")
public class ProjectLeader implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private int id;
//bi-directional many-to-one association to Project
@OneToMany(mappedBy="projectLeader",fetch=FetchType.EAGER,orphanRemoval=true)
private List<Project> projects;
public ProjectLeader() {
}
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public List<Project> getProjects() {
return this.projects;
}
public void setProjects(List<Project> projects) {
this.projects = projects;
}
public Project addProject(Project project) {
getProjects().add(project);
project.setProjectLeader(this);
return project;
}
public Project removeProject(Project project) {
getProjects().remove(project);
project.setProjectLeader(null);
return project;
}
}
和测试class
package leader;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.PersistenceUnit;
public class Test {
@PersistenceUnit(unitName="leader")
EntityManagerFactory emf1;
public static void main(String[] args) {
Project projectA = new Project();
projectA.setId(1);
Project projectB = new Project();
projectB.setId(2);
ProjectLeader leaderA = new ProjectLeader();
leaderA.setId(1);
ProjectLeader leaderB = new ProjectLeader();
leaderB.setId(2);
EntityManagerFactory emf = Persistence.createEntityManagerFactory("leader");
EntityManager em=emf.createEntityManager();
em.getTransaction().begin();
em.persist(leaderA);
em.persist(leaderB);
// projectA.setProjectLeader(leaderA);
projectA.setProjectLeader(leaderB);
projectB.setProjectLeader(leaderA);
// projectB.setProjectLeader(leaderB);
em.persist(projectA);
em.persist(projectB);
em.getTransaction().commit();
}
}
我遇到这种情况:
@Entity
@Table(name = "project_leader")
public class ProjectLeader {
@ManyToOne
@JoinColumn(name = "projectId")
@JsonBackReference(value = "project")
private Project project;
...
和相关实体
@Entity
@Table(name = "project")
public class Project {
@OneToMany(fetch = FetchType.EAGER, mappedBy = "project", orphanRemoval = true)
@Cascade(CascadeType.ALL)
@JsonManagedReference(value = "project")
private Set<ProjectLeader> projectLeaders = new HashSet<ProjectLeader>();
例如情况
Project_A 与 ProjectLeader_1 和 Project_B 和 ProjectLeader_2
当我尝试将 ProjectLeader_1 添加到 Project_B 时,我也得到 ProjectLeader_1 从 Project_A 完全移动到 Project_B,所以我有以下内容情况:
Project_A with -No leader- and Project_B 与 ProjectLeader_2 ProjectLeader_1
理想的结果应该是:
Project_A 与 ProjectLeader_1 和 Project_B 与 ProjectLeader_2 ProjectLeader_1
项目负责人分配方法如下:
private Project initializeProject(@Nonnull ProjectDto projectDto) {
Project project = null;
if (projectDto.getId() != null) {
project = projectRepository.findOne(projectDto.getId());
} else {
project = new Project();
}
project.setName(projectDto.getName());
project.setProjectType(projectDto.getProjectType());
project.setFinancedBy(projectDto.getFinancedBy());
Set<ProjectLeader> projectLeaders = new HashSet<ProjectLeader>();
for (ProjectLeaderDto projectLeaderDto : projectDto.getProjectLeaderDtos()) {
ProjectLeader projectLeader = new ProjectLeader();
Professor professor = null;
if (projectLeaderDto.getId() != null && projectLeaderDto.getId() > 0L) {
projectLeader = projectLeaderRepository.findOne(projectLeaderDto.getId());
}
if (projectLeaderDto.getProfessorId() != null && projectLeaderDto.getProfessorId() > 0L) {
professor = professorRepository.findOne(projectLeaderDto.getProfessorId());
}
projectLeader.setName(projectLeaderDto.getName());
projectLeader.setSurname(projectLeaderDto.getSurname());
projectLeader.setProject(project);
projectLeader.setProfessor(professor);
projectLeaders.add(projectLeader);
}
// If collection from Dto miss some element from original collection, we
// remove it from original
Iterator<ProjectLeader> currentLeadersIterator = project.getProjectLeaders().iterator();
while (currentLeadersIterator.hasNext()) {
ProjectLeader projectLeader = currentLeadersIterator.next();
if (!projectLeaders.contains(projectLeader)) {
currentLeadersIterator.remove();
projectLeader.setProject(null);
}
}
// If original collection miss some element from Dto collection, we add
// it to original
Iterator<ProjectLeader> newLeadersIterator = projectLeaders.iterator();
while (newLeadersIterator.hasNext()) {
ProjectLeader projectLeader = newLeadersIterator.next();
if (!project.getProjectLeaders().contains(projectLeader)) {
project.getProjectLeaders().add(projectLeader);
projectLeader.setProject(project);
}
}
return project;
}
这可能是什么原因?
我是新来的所以请 post 我 link 如果其他地方有类似的问题。 谢谢。
我认为插入有问题,请注意每个项目都有一个项目负责人,所以如果你把另一个负责人放到项目中,旧的会被删除,新的会插入,我写了一个小程序关于你的问题:
package leader;
import java.io.Serializable;
import javax.persistence.*;
/**
* The persistent class for the Project database table.
*
*/
@Entity
@NamedQuery(name="Project.findAll", query="SELECT p FROM Project p")
public class Project implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private int id;
//bi-directional many-to-one association to ProjectLeader
@ManyToOne
@JoinColumn(name="Leader_Id")
private ProjectLeader projectLeader;
public Project() {
}
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public ProjectLeader getProjectLeader() {
return this.projectLeader;
}
public void setProjectLeader(ProjectLeader projectLeader) {
this.projectLeader = projectLeader;
}
}
项目负责人class:
package leader;
import java.io.Serializable;
import javax.persistence.*;
import java.util.List;
@Entity
@NamedQuery(name="ProjectLeader.findAll", query="SELECT p FROM ProjectLeader p")
public class ProjectLeader implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private int id;
//bi-directional many-to-one association to Project
@OneToMany(mappedBy="projectLeader",fetch=FetchType.EAGER,orphanRemoval=true)
private List<Project> projects;
public ProjectLeader() {
}
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public List<Project> getProjects() {
return this.projects;
}
public void setProjects(List<Project> projects) {
this.projects = projects;
}
public Project addProject(Project project) {
getProjects().add(project);
project.setProjectLeader(this);
return project;
}
public Project removeProject(Project project) {
getProjects().remove(project);
project.setProjectLeader(null);
return project;
}
}
和测试class
package leader;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.PersistenceUnit;
public class Test {
@PersistenceUnit(unitName="leader")
EntityManagerFactory emf1;
public static void main(String[] args) {
Project projectA = new Project();
projectA.setId(1);
Project projectB = new Project();
projectB.setId(2);
ProjectLeader leaderA = new ProjectLeader();
leaderA.setId(1);
ProjectLeader leaderB = new ProjectLeader();
leaderB.setId(2);
EntityManagerFactory emf = Persistence.createEntityManagerFactory("leader");
EntityManager em=emf.createEntityManager();
em.getTransaction().begin();
em.persist(leaderA);
em.persist(leaderB);
// projectA.setProjectLeader(leaderA);
projectA.setProjectLeader(leaderB);
projectB.setProjectLeader(leaderA);
// projectB.setProjectLeader(leaderB);
em.persist(projectA);
em.persist(projectB);
em.getTransaction().commit();
}
}