[英]Hibernate, Spring. Multiple representations of the same entity are being merged
嘗試更新實體列表(作業)時出現錯誤:
Multiple representations of the same entity [com.introlabsystems.upworkscraper.model.entities.Skill#42] are being merged. Detached: [Skill(id=42, skillName=Web Scraping)]; Detached: [Skill(id=42, skillName=Web Scraping)]
我認為這是在三個實體與技能實體具有多對多關系的情況下。
@Entity
public class Job {
@Id
@Column(unique = true, nullable = false)
@SerializedName(value = "ciphertext")
private String id;
@Column(length = 2048)
private String title;
@Column(columnDefinition = "TEXT")
@JsonAdapter(value = DescriptionAdapter.class)
private String description;
@SerializedName(value = "subcategory2")
private String category;
@ManyToMany(cascade = {
CascadeType.MERGE
}, fetch = FetchType.EAGER)
@JoinTable(
joinColumns = {@JoinColumn(name = "job_id")},
inverseJoinColumns = {@JoinColumn(name = "skill_id")}
)
@JsonAdapter(value = SkillsAdapter.class)
private Set<Skill> skills;
private String duration;
private String engagement;
@JsonAdapter(value = AmountAdapter.class)
private String amount;
@JsonAdapter(value = AmountAdapter.class)
private String maxAmount;
private String freelancersToHire;
private String enterpriseJob;
private String proposalsTier;
private String stickyLabel;
@SerializedName(value = "tierLabel")
private String tier;
@JsonAdapter(value = DateTimeAdapter.class)
private LocalDateTime createdOn;
@JsonAdapter(value = DateTimeAdapter.class)
private LocalDateTime publishedOn;
@JsonAdapter(value = DateTimeAdapter.class)
private LocalDateTime renewedOn;
private LocalDateTime hiredOn;
@OneToOne(cascade = CascadeType.ALL)
private Contract contract;
@SerializedName(value = "type")
@JsonAdapter(value = JobTypeAdapter.class)
@Enumerated(value = EnumType.STRING)
private JobType jobType;
@Enumerated(value = EnumType.STRING)
private JobStatus jobStatus = JobStatus.OPEN;
private String projectStage;
private String ongoingProject;
private String projectType;
private String finalOutput;
private String Platform;
private String oneTimeProject;
private String jobSuccessScore;
private String includeRisingTalent;
private String englishLevel;
private String upworkHours;
private String freelancerType;
private String preferredLocation;
private String interviewing;
@OneToOne(cascade = CascadeType.ALL)
private PrivateStatus privateStatus;
}
@Data
@Entity
public class Skill {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String skillName;
}
@Data
@Entity
public class Contract {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@JsonAdapter(value = ContractJobIdAdapter.class)
@SerializedName(value = "jobInfo")
private String jobId;
private String totalCharge;
private String totalHours;
@JsonAdapter(value = AmountAdapter.class)
private String rate;
@JsonAdapter(value = DateTimeAdapter.class)
private LocalDateTime startDate;
@JsonAdapter(value = DateTimeAdapter.class)
private LocalDateTime endDate;
@ManyToOne(cascade = CascadeType.MERGE)
@SerializedName(value = "contractorInfo")
private Freelancer freelancer;
@ManyToOne(cascade = CascadeType.ALL)
private Client client;
}
@Data
@Entity
public class Freelancer {
@Id
@SerializedName(value = "ciphertext")
private String id;
@SerializedName(value = "contractorName")
private String name;
@Column(length = 2048)
private String title;
@Column(columnDefinition = "TEXT")
@JsonAdapter(value = DescriptionAdapter.class)
private String description;
@JsonAdapter(value = FreelancerLocationAdapter.class)
private String location;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(
joinColumns = {@JoinColumn(name = "freelancer_id")},
inverseJoinColumns = {@JoinColumn(name = "skill_id")}
)
@JsonAdapter(value = SkillsAdapter.class)
private Set<Skill> skills;
private String hourlyRate;
private String privateFeedbackHireAgain;
private String rating;
private String scores;
private String totalEarnings;
private String totalFeedback;
private String totalFixedJobs;
private String totalHourlyJobs;
private String totalHours;
private String totalJobsWorked;
private String topRatedStatus;
private String successScore;
@OneToMany(cascade = CascadeType.ALL)
private List<ContractHistory> contractHistories;
@ManyToMany(cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
})
@JoinTable(
joinColumns = {@JoinColumn(name = "freelancer_id")},
inverseJoinColumns = {@JoinColumn(name = "agency_id")}
)
private Set<Agency> agency;
}
@Data
@Entity
public class Agency {
@Id
@SerializedName(value = "chipertext")
private String id;
@JsonAdapter(value = AmountAdapter.class)
private String minRate;
@JsonAdapter(value = AmountAdapter.class)
private String maxRate;
private String city;
private String country;
@Column(columnDefinition = "TEXT")
@JsonAdapter(value = DescriptionAdapter.class)
private String description;
private String jobSuccessScore;
private String name;
@Column(length = 2048)
private String title;
private String topRatedStatus;
private String totalEarnings;
private String totalHours;
private String totalJobs;
private String recentEarnings;
private String averageRecentEarnings;
@JsonAdapter(value = DateTimeAdapter.class)
private LocalDateTime memberSince;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(
joinColumns = {@JoinColumn(name = "agency_id")},
inverseJoinColumns = {@JoinColumn(name = "skill_id")}
)
@JsonAdapter(value = SkillsAdapter.class)
private Set<Skill> skills;
}
我試圖挽救一份工作。 在此之前,我從工作、代理機構、自由職業者那里獲得技能,嘗試在數據庫中搜索它們並替換 ID。
for (Skill skill: skills) { Skill skillWithID = skillDataService.findBySkillName(skill.getSkillName()) .orElseGet(() -> skillDataService.save(skill)); skill.setId(skillWithID.getId()); }
改變了
CascadeType.MERGE
到
CascadeType.PERSIST,
CascadeType.DETACH,
CascadeType.REFRESH,
CascadeType.REMOVE
它有效
您面臨這個問題是因為您正在將對象添加到已經可用的列表中。同時使用 oneToMany 映射執行保存操作
現在從級聯中刪除 CascadeType.MERGE 是一種解決方案,但不是最好的解決方案,因為從級聯中刪除 MERGE 后,您將永遠無法更新映射對象
如果您還想對映射對象執行更新操作和保存,那么在將映射對象添加到列表/集合之前,只需在列表中檢查/搜索對象,如果映射對象在列表中可用,則對該特定對象執行操作目的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.