簡體   English   中英

冬眠,春天。 正在合並同一實體的多個表示

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM