[英]How to save multiple entity in one action related in Many to Many Relationship [Spring Boot 2, JPA, Hibernate, PostgreSQL]
[英]how to delete or save a many to many relationship in hibernate & spring
我在2张桌子之间有很多对很多的关系。 以下是带有映射的两个表。 StaffSearchCriteria用于搜索具有所选技能的人员。 此搜索条件将保留在数据库中,以便我们以后可以再次查找它。
我面临的问题是我无法正确保存此数据。 我不了解映射的“级联”部分。 因此,如果我执行“ Cascade.ALL
”,则数据将正确保存,但是当我删除搜索条件时,它也会删除与之关联的Skill
条目,这是错误的。 我只希望如果我删除Skill, StaffSearchCriteria
条目就不会被删除,并且对于该Skill
类似; 仅应删除所选数据并将其输入到映射表中。 另一个表不应受到该操作的影响。
@Entity
@Table(name = "staff_search_criteria")
@NamedQueries({
@NamedQuery(name = "StaffSearchCriteria.findAll", query = "SELECT s FROM StaffSearchCriteria s")})
public class StaffSearchCriteria implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id")
private Long id;
@Basic(optional = false)
@NotNull
@Column(name = "version")
private long version;
@Lob
@Size(max = 2147483647)
@Column(name = "description")
private String description;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 200)
@Column(name = "name")
private String name;
@ManyToMany(mappedBy = "staffSearchCriteriaCollection", cascade = {CascadeType.MERGE, CascadeType.PERSIST}, fetch = FetchType.LAZY)
private Collection<Skill> skillCollection;
==================================================
@Entity
@Table(name = "skill")
@NamedQueries({
@NamedQuery(name = "Skill.findAll", query = "SELECT s FROM Skill s")})
public class Skill implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id")
private Long id;
@Basic(optional = false)
@NotNull
@Column(name = "version")
private long version;
@Lob
@Size(max = 2147483647)
@Column(name = "description")
private String description;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 100)
@Column(name = "name")
private String name;
@JoinTable(name = "mission_skill", joinColumns = {
@JoinColumn(name = "skill_id", referencedColumnName = "id")}, inverseJoinColumns = {
@JoinColumn(name = "mission_skills_id", referencedColumnName = "id")})
@ManyToMany(fetch = FetchType.LAZY)
private Collection<Mission> missionCollection;
@JoinTable(name = "staff_search_criteria_skill", joinColumns = {
@JoinColumn(name = "skill_id", referencedColumnName = "id")}, inverseJoinColumns = {
@JoinColumn(name = "staff_search_criteria_skills_id", referencedColumnName = "id")})
@ManyToMany(cascade = {CascadeType.MERGE, CascadeType.PERSIST}, fetch = FetchType.LAZY)
private Collection<StaffSearchCriteria> staffSearchCriteriaCollection;
public StaffSearchCriteria saveStaffSearchCriteria(StaffSearchCriteria staffSearchCriteria) {
logger.info(" [StaffSearchCriteriaDAOImpl] saveStaffSearchCriteria method called. - staffSearchCriteria = " + staffSearchCriteria);
Session session = sessionFactory.getCurrentSession();
session.saveOrUpdate(staffSearchCriteria);
return staffSearchCriteria;
}
public void deleteStaffSearchCriteria(Long id) {
logger.info(" [StaffSearchCriteriaDAOImpl] deleteStaffSearchCriteria method called. - id = " + id);
Session session = sessionFactory.getCurrentSession();
Query query = session.createQuery("FROM StaffSearchCriteria ssc where ssc.id = " + id);
if(null != query.uniqueResult()){
StaffSearchCriteria staffSearchCriteria = (StaffSearchCriteria)query.uniqueResult();
session.delete(staffSearchCriteria);
}
}
请在这里帮助我。我在做什么错?
终于我解决了。 我所做的如下。
1.在控制器中,我发现从以前保存的数据中删除了哪些技能。
2.将技能列表以及StaffSearchCriteria传递给服务保存方法。
3.在服务中,我遍历要删除的每个技能,并从中删除了staffSearchCriteria对象并保存了它。
4.然后将人员搜索条件传递给dao,并使用saveOrUpdate方法。
以下是代码片段。
1.Controller
List<Skill> skillList2 = new ArrayList<Skill>();
if(null != request.getParameterValues("skillCollection")){
for(String skillId : request.getParameterValues("skillCollection")){
if((!skillId.equals(null)) && skillId.length() > 0){
Skill skill = skillService.findSkillById(Long.parseLong(skillId));
// skill will be lazily initialized :(
// initialize it
skill.setStaffSearchCriteriaCollection(staffSearchCriteriaService.getAllStaffSearchCriteriaBySkillId(skill.getId()));
// set staff search criteria in each skill. because it is the owner
if(null != skill.getStaffSearchCriteriaCollection()){
skill.getStaffSearchCriteriaCollection().add(staffSearchCriteria);
}else{
List<StaffSearchCriteria> staffSearchCriteriaList = new ArrayList<StaffSearchCriteria>();
staffSearchCriteriaList.add(staffSearchCriteria);
skill.setStaffSearchCriteriaCollection(staffSearchCriteriaList);
}
skillList2.add(skill);
}
}
}
staffSearchCriteria.setSkillCollection(skillList2);
// Remove OLD skills also. plz. :)
List<Skill> skillList3 = null;
if(null != staffSearchCriteria && staffSearchCriteria.getId() != null && staffSearchCriteria.getId() > 0){
// this skillList3 will contain only those which are removed.
skillList3 = skillService.getAllSkillByStaffSearchCriteriaId(staffSearchCriteria.getId());
skillList3.removeAll(skillList2);
}
// now set staffSearchCriteriacollection and then pass it.
List<Skill> removedskillList = new ArrayList<Skill>();
if(null != skillList3){
for(Skill skill : skillList3){
skill.setStaffSearchCriteriaCollection(staffSearchCriteriaService.getAllStaffSearchCriteriaBySkillId(skill.getId()));
removedskillList.add(skill);
}
}
// now pass to service and save these skills after removing this staff search criteria from them.
staffSearchCriteria = staffSearchCriteriaService.saveStaffSearchCriteria(staffSearchCriteria, removedskillList);
2.Service
if(null != removedskillList && removedskillList.size() > 0){
for(Skill skill : removedskillList){
skill.getStaffSearchCriteriaCollection().remove(staffSearchCriteria);
skillDAO.saveSkill(skill);
}
}
return staffSearchCriteriaDAO.saveStaffSearchCriteria(staffSearchCriteria);
3.DAO
Session session = sessionFactory.getCurrentSession();
session.saveOrUpdate(staffSearchCriteria);
4.实体课-技能
@JoinTable(name = "staff_search_criteria_skill", joinColumns = {
@JoinColumn(name = "skill_id", referencedColumnName = "id")}, inverseJoinColumns = {
@JoinColumn(name = "staff_search_criteria_skills_id", referencedColumnName = "id")})
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.LAZY)
private Collection<StaffSearchCriteria> staffSearchCriteriaCollection = new ArrayList<StaffSearchCriteria>();
5,实体类-StaffSearchCriteria
@ManyToMany(mappedBy = "staffSearchCriteriaCollection", fetch = FetchType.LAZY, cascade = {CascadeType.ALL})
private Collection<Skill> skillCollection = new ArrayList<Skill>();
希望这可以帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.