【问题标题】:Duplicate entity for key 'PRIMARY'键“P​​RIMARY”的重复实体
【发布时间】:2017-10-16 13:47:06
【问题描述】:

我的问题是,当我让级联持续存在时,它会引发异常 (MySQLIntegrityConstraintViolationException)。 我正在使用Spring Data; 来保存我的数据。

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: 键“P​​RIMARY”的重复条目“Bloomberg”

News.class:

@Entity
public class News implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "company_name")
    private Company company;

    ...
}

Company.class:

@Entity
@Table(name = "company")
public class Company implements Serializable{

    @Id
    @Column(unique = true,nullable = false)
    private String name;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "company",fetch = FetchType.EAGER)
    private List<News> newsList;

   ...
}

我正在使用此代码来坚持:

public void parseDB() throws IOException {
    List<News> newsList = new ArrayList<>();

    Map<String, Company> companyMap = ((List<Company>) companyRepository.findAll()).stream().collect(Collectors.toMap(Company::getName, company -> company));

    newsList.addAll(WebPagesParser.parseCategory("...", "...", companyMap));
    newsList.forEach(newsService::create);
    }


public static List<News> parseCategory(String url, String category,Map<String,Company> companyMap) throws IOException {
       ... 
      Company company; 
      if (companyMap.containsKey(name)) {
                    company = companyMap.get(name);
                } else {
                    company = new Company();
                    company.setName(top.get(1).text());
                }
       news.setCompany(company);
      ...
      }

它给了我新的例外

org.springframework.dao.InvalidDataAccessApiUsageException:分离 传递给持久化的实体:com.example.inosmi.database.data.News; 嵌套异常是 org.hibernate.PersistentObjectException: detached 传递给持久化的实体:com.example.inosmi.database.data.News

完成: 已经解决了我的一半问题,我仍然不知道它在哪里,但它可以工作。谢谢大家!

【问题讨论】:

  • 您正在尝试使用数据库中已经存在的主键插入一行。
  • 我想合并它,但它没有。
  • 如果你正在使用一个和你的合并/持久代码,你能告诉我们你的查询吗?
  • 您必须先从数据库中获取相同的实体,然后再更新它。

标签: java mysql sql hibernate jpa


【解决方案1】:

MySQL 告诉您您正在尝试使用相同的主键插入多行

与此相关的代码在这里

@Id
@Column(unique = true, nullable = false)
private String name;

您正在加载的数据有多行,公司名称为Bloomberg

【讨论】:

  • 我完全理解它,我希望它把这家公司的对象合并到一个实体中。
  • 然后确保您正在加载公司对象,而不是创建新对象。当您调用 News#setCompany 时,参数必须是您已经从数据库加载的参数,而不是您刚刚使用 new Company(...) 创建的参数
  • 谷歌搜索的最高结果是错误指向stackoverflow.com/q/13370221/134894
【解决方案2】:

@OneToMany 使用 Set 而不是 List,否则维护一个 index

@OneToMany(cascade = CascadeType.ALL, mappedBy = "company",fetch = FetchType.EAGER)
private Set<News> newsList;

【讨论】:

    猜你喜欢
    • 2012-04-05
    • 2016-10-30
    • 1970-01-01
    • 2011-10-08
    • 1970-01-01
    • 2014-10-08
    • 2015-02-10
    • 2021-08-16
    • 2014-06-05
    相关资源
    最近更新 更多