【问题标题】:Hibernate(JPA) Duplicate entry '25-9' for key 'PRIMARY'休眠(JPA)键“PRIMARY”的重复条目“25-9”
【发布时间】:2013-03-05 15:32:49
【问题描述】:

我有一个包含亲子关系的应用程序。每个父母都有一组孩子(一对多),每个孩子都有一个父母(多对一)。 在应用程序中,我有一个服务层,在那里我几乎做了以下事情:

  public void addChild() {
       parent = getParentFromDB();
       Child child = new Child();
       child.setParent(parent);
       saveChild(child);
       Set<Child> children = new HashSet<Child>();
       children.addAll(parent.getChildren());
       children.add(child);

       parent.setChildren(children); // notice this line here.

       saveParent(parent);
       doStuff(parent);
    }

服务层是从一个外观调用的,它是一个带有@Transactional注解的常规Spring bean。当我尝试调用addChild() 方法时,我得到以下结果:

2013-03-05 17:09:50,195 [qtp511931089-83] WARN  org.hibernate.engine.jdbc.spi.SqlExceptionHelper - SQL Error: 1062, SQLState: 23000
2013-03-05 17:09:50,196 [qtp511931089-83] ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper - Duplicate entry '25-9' for key 'PRIMARY'
2013-03-05 17:09:50,198 [qtp511931089-83] ERROR org.hibernate.engine.jdbc.batch.internal.BatchingBatch - HHH000315: Exception executing batch [Duplicate entry '25-9' for key 'PRIMARY']
2013-03-05 17:09:50.204:WARN:oejs.ServletHandler:/child/add
javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: Duplicate entry '25-9' for key 'PRIMARY'
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1377)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1300)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1306)

我确实在休眠状态下打开了 SQL 日志,似乎休眠状态调用了两次保存!!!如果我删除“//在此处注意此行”行,则一切正常-实体保存在数据库中,我可以在数据库中看到 25-9 关系。问题是在方法的最后我有 doStuff(parent);与父母及其孩子做一些事情的方法,所以我不能删除“//在此处注意这一行”行

编辑: 这是在孩子中声明父母的方式:

@ManyToOne(fetch = FetchType.EAGER, targetEntity = ParentModel.class, cascade = { CascadeType.REMOVE })
@JoinTable(name = "PARENT_CHILDREN", joinColumns = @JoinColumn(name = "CHILD_ID"), inverseJoinColumns = @JoinColumn(name = "PARENT_ID"))
private ParentModel parent;

这是在父级中声明子级的方式:

@OneToMany(fetch = FetchType.LAZY, targetEntity = ChildModel.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE })
@JoinTable(name = "PARENT_CHILDREN", joinColumns = @JoinColumn(name = "PARENT_ID"), inverseJoinColumns = @JoinColumn(name = "CHILD_ID"))
private Set<ChildModel> children;

【问题讨论】:

  • 请发布父子关系定义
  • 您在持久化依赖实体的方式中存在配置错误。可以发一下parent和child的映射关系吗?

标签: jpa duplicates parent many-to-one


【解决方案1】:

您似乎只是缺少关系中的mappedBy 参数:

@OneToMany(mappedBy="parent", fetch = FetchType.LAZY, targetEntity = ChildModel.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE })
@JoinTable(name = "PARENT_CHILDREN", joinColumns = @JoinColumn(name = "PARENT_ID"), inverseJoinColumns = @JoinColumn(name = "CHILD_ID"))
private Set<ChildModel> children;

【讨论】:

  • 如果我添加了 mappedBy 参数,我会在启动期间收到此异常: 原因:org.hibernate.AnnotationException:标记为 mappedBy 的关联不得定义数据库映射,如 \@JoinTable 或 @JoinColumn: xxxx.ParentModel .children
  • 那么删除 JoinTable 怎么样?
  • 我会接受你的回答。它实现了我所追求的,尽管它以不同的方式实现。我最终的配置是:@ManyToOne(fetch = FetchType.EAGER, targetEntity = ParentModel.class, cascade = { CascadeType.REMOVE }) @JoinColumn(name = "PARENT_ID", nullable = true, referencedColumnName = "PK")私有 ParentModel 父级;和@OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, targetEntity = ChildrenModel.class, cascade = { CascadeType.REMOVE }) private Set children;
  • @ben75 我也有类似的问题。你愿意帮助我吗?这是链接:stackoverflow.com/questions/25316761/…
猜你喜欢
  • 1970-01-01
  • 2016-10-25
  • 2019-04-04
  • 1970-01-01
  • 2017-02-17
  • 2014-04-13
  • 1970-01-01
  • 2012-07-23
  • 2013-09-30
相关资源
最近更新 更多