【问题标题】:ORA-02292 when using HibernateORA-02292 使用休眠时
【发布时间】:2015-06-24 09:22:54
【问题描述】:

我正在尝试实现删除功能,但我得到的只是这个 ORA-02292 错误:

Caused by: java.sql.SQLIntegrityConstraintViolationException: ORA-02292: Integritäts-Constraint (VDMA.FK892DE8B473F40868) verletzt - untergeordneter Datensatz gefunden

    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:447)
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:396)
    at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:951)

我有一个实体 (MainEntity),它与其子实体有 n:m 关系。

例如:一个用户可以拥有多辆汽车,每辆汽车可以由不同的用户驾驶。

当用户被删除时,我希望用户和汽车之间的关联也被删除。这就是为什么我认为我可以做到以下几点:

用户实体

@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name = "user_car", joinColumns = {@JoinColumn(name = DATABASE_COLUMN_ID, nullable = false, updatable = false) }, inverseJoinColumns = {@JoinColumn(name = DATABASE_COLUMN_TYPE_ID,
      nullable = true, updatable = false) })
private Set<UserCar> userCars;

汽车实体

@ManyToMany(fetch = FetchType.LAZY, mappedBy = "userCars")
  private Set<User> users;

结果是:

表被创建,数据被持久化——一切正常。 除了删除条目:一旦我尝试删除用户并且用户有汽车(因此用户:汽车关系),我确实会收到上面显示的错误。

如果用户没有任何汽车,我可以毫无问题地删除他。所以问题一定是USER_CAR表中的约束。

【问题讨论】:

  • private Set&lt;UserCar&gt; userCars; 中的UserCar 实体是什么?它是映射到类似CAR 表的汽车,而 USER_CAR 是用户和汽车之间的连接表吗?

标签: java oracle hibernate jpa


【解决方案1】:

也清除userCars

user.getUserCars().clear()

这会破坏用户和关联汽车之间的关联(它会从联结表中删除相应的记录)。

此外,您不希望在多对多关联中使用CascadeType.ALL,因为它隐含包含CascadeType.REMOVE。使用它意味着移除也将级联到汽车,尽管还有其他用户与这些汽车相关联。

【讨论】:

  • 删除用户之前。
  • 注意,因为 Hari 和 aksamit 已经偶然发现它:为什么你有一个隐含的 ManyToManyCascadeType.REMOVE(在 cascade=CascadeType.ALL 中)? CascadeType.REMOVE 仅对 OneToX 关系有意义,因为它意味着在删除父实体时删除引用的实体。
  • @TobiasLiefke 你说得对,谢谢!我没有注意到 OP 使用它。我编辑了我的答案以包含该警告。
  • @Dragan : 那么哪个 CasecadeType 是正确的呢?
  • 哪个适合您的用例。要包括除REMOVE 之外的所有内容,您可以指定cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH, CascadeType.DETACH}。但排除那些你不会使用的; PERSISTMERGE 在大多数用例中通常就足够了。
【解决方案2】:

请确保删除子记录,添加 orphanRemoval 会有所帮助

@ManyToMany(fetch = FetchType.LAZY, cascade =         CascadeType.ALL,orphanRemoval=true)

@JoinTable(name = "user_car", joinColumns = {@JoinColumn(name = DATABASE_COLUMN_ID, nullable = false, updatable = false) }, inverseJoinColumns = {@JoinColumn(name = DATABASE_COLUMN_TYPE_ID, 可空=真,可更新=假)}) 私人设置 userCars;

这将删除与用户关联的所有汽车。

【讨论】:

  • 我可以看到 ic 可以将该属性添加到 OneToMany 但不是 ManyToMany 关系......还有其他选择吗?
  • 抱歉没有注意到它是ManyToMany,只有在源端具有单一基数的关系才能启用孤儿删除,这就是为什么在“@OneToOne”和“@OneToMany”关系上定义了orphanRemoval选项的原因注释,但不在“@ManyToOne”或“@ManyToMany”注释上。
  • ManyToMany 的任何解决方案?
猜你喜欢
  • 1970-01-01
  • 2014-04-14
  • 2018-11-14
  • 2016-05-06
  • 2020-04-08
  • 2016-04-13
  • 1970-01-01
  • 2012-07-09
  • 1970-01-01
相关资源
最近更新 更多