Спящий, Весна.Несколько представлений одного и того же объекта объединяются - PullRequest
0 голосов
/ 28 сентября 2018

Я получаю сообщение об ошибке при попытке обновить список сущностей (Job):

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)]

Я думаю, что в случае, если три сущности имеют отношения ManyToMany с сущностью Skill.

@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;
}

Я пытаюсь сохранить работу.Перед этим я получаю навыки от работы, агентства, фрилансера, пытаюсь найти их в БД и подставить идентификаторы.

    for (Skill skill: skills) 
    {
        Skill skillWithID = 
        skillDataService.findBySkillName(skill.getSkillName())
          .orElseGet(() -> skillDataService.save(skill));
        skill.setId(skillWithID.getId());
    }

1 Ответ

0 голосов
/ 23 октября 2018

Изменено

CascadeType.MERGE

на

CascadeType.PERSIST,
CascadeType.DETACH,
CascadeType.REFRESH,
CascadeType.REMOVE

и все работает

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...