以下情况。我有三个班级(简历=简历,专业经验和行业)。我的REST控制器收到更新现有CV的PUT请求。 JSON看起来像这样:
{
"id": 102,
"currentSalery":100,
"desiredSalery":120,
"professionalExperiences": [
{ "jobTitle" : "Technical Project Lead", "company" : "Example Company 1",
"monthStart" : 10, "yearStart" : 2008, "monthEnd" : 11, "yearEnd" : 2017, "industry" : {"id" : 1001, "name" : "IT"}
},
{ "jobTitle" : "Software Consultant", "company" : "Example Company 2",
"monthStart" : 11, "yearStart" : 2017, "industry" : {"name" : "Sales"}
}
]}
CV和ProfessionalExperience之间的关系是1:n。 ProfessionalExperience与Industry之间的关系是n:1。请注意,JSON可以将现有的Industry Objects作为引用(此处为IT)或新的(此处为Sales)。
这里(我希望)是ProfessionalExperience和Industry class的所有重要部分
ProfessionalExperience:
@Entity
public class ProfessionalExperience implements Serializable {
@Id
@SequenceGenerator(name="prof_seq", initialValue=1, allocationSize=100)
@GeneratedValue(strategy= GenerationType.SEQUENCE, generator="prof_seq")
private Long id;
@ManyToOne(fetch=FetchType.LAZY, cascade=CascadeType.ALL)
@JoinColumn(name = "industry_id")
private Industry industry;
@JsonIgnore
@ManyToOne
@JoinColumn(name = "cv_id")
private CV cv;
public Industry getIndustry() {
return industry;
}
/**
* Set new industry. The method keeps relationships consistency
* * this professionalExperience is removed from the previous industry
* * this professionalExperience is added to next industry
*
* @param industry
*/
public void setIndustry(Industry industry) {
//prevent endless loop
if (sameAsFormer(industry))
return ;
//set new industry
Industry oldIndustry = this.industry;
this.industry = industry;
//remove from the industry
if (oldIndustry!=null)
oldIndustry.removeProfessionalExperience(this);
//set myself into industry
if (industry!=null)
industry.addProfessionalExperience(this);
}
private boolean sameAsFormer(Industry newIndustry) {
return industry==null? newIndustry == null : industry.equals(newIndustry);
}
}
我实现了JPA/Hibernate: detached entity passed to persist中提到的setter但没有成功。
行业:
@Entity
public class Industry implements Serializable {
@Id
@SequenceGenerator(name="industry_seq", initialValue=1, allocationSize=100)
@GeneratedValue(strategy= GenerationType.SEQUENCE, generator="industry_seq")
private Long id;
// REMOVED cascade = CascadeType.ALL for testing
@JsonIgnore
@OneToMany(mappedBy = "industry")
private List<ProfessionalExperience> professionalExperiences = new ArrayList<>();
/**
* Returns a collection with owned professional experiences. The
* returned collection is a defensive copy.
*
* @return a collection with owned professional experiences
*/
public List<ProfessionalExperience> getProfessionalExperiences() {
return new ArrayList<ProfessionalExperience>(professionalExperiences);
}
/**
* Add new professionalExperience to the industry. The method keeps
* relationships consistency:
*/
public void addProfessionalExperience(ProfessionalExperience professionalExperience) {
// prevent endless loop
if(professionalExperiences.contains(professionalExperience))
return;
professionalExperiences.add(professionalExperience);
professionalExperience.setIndustry(this);
}
/**
* Removes the professionalExperience from the industry. The method keeps
* relationships consistency:
*/
public void removeProfessionalExperience (ProfessionalExperience professionalExperience) {
// prevent endless loop
if(!professionalExperiences.contains(professionalExperience))
return;
professionalExperiences.remove(professionalExperience);
professionalExperience.setIndustry(null);
} }
我在ProfessionalExperience的一个行业方面玩过不同的CascadeTypes组合,但从来没有得到正确的组合。如果我从Industry中删除CascadeType,我就得到
Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist: x.y.z.Industry
两侧都有CascadeType.ALL,它取决于我想要保存的Industry对象。如果有所有新的(或没有重复),那么它正在工作。但是如果两个ProfessionalExperiences引用相同的Industry对象,我会得到这个:
Caused by: java.lang.IllegalStateException: Multiple representations of the same entity [x.y.z.Industry#303] are being merged
有人可以帮帮我吗?提前完成!
答案 0 :(得分:0)
你让关系变得有点复杂:) 虽然关系取决于您的使用案例,但我仍然建议建立这样的关系:
同样制作行业,元数据,即它将拥有自己的生命周期(您需要在使用之前保存它)
此外,如果您需要按行业划分的所有专业经验,那么您可以通过触发其他查询来获取它们,例如<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<input v-model="tax" type="number" >
<button @click="reset">Reset</button>
</div>
。
P.S。启用二级缓存。它将与数据库分担性能负担。
答案 1 :(得分:0)
最后修好了。我犯了两个错误
ManyToOne
)并再次向行业添加CascadeType.ALL
我的自动生成等于ProfessionalExperience中的方法不正确:
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof ProfessionalExperience)) return false;
ProfessionalExperience that = (ProfessionalExperience) o;
return id != null ? id.equals(that.id) : that.id == null;
}
如果我们比较两个未保存的ProfessionalExperiences,则返回true,因此contains
中的addProfessionalExperience
未按预期工作。我刚刚将最后一行更改为return id != null ? id.equals(that.id) : that.id != null
,工作正常。
这最终让我有了限制,我无法分配未保存的行业,但Narender Singh已经提到了如何处理这个问题。