【问题标题】:How to avoid foreign-key-constraint violations using pure JPA/Hibernate annotations如何使用纯 JPA/Hibernate 注释避免外键约束违规
【发布时间】:2014-09-28 02:58:09
【问题描述】:

我正在处理我的数据库模型的问题有一段时间了。我使用 Hibernate 来管理我的实体,整个事物都存储在 HSQLDB(内存数据库) 中,因此表是由 hibernate 在运行时创建的。我的注释类的一个简短示例如下所示:

@Entity
@Table(name = "Paper")
public class Paper {
  @Id
  @Column(name = "ID")
  private Long id;

  @ManyToMany(fetch = FetchType.LAZY)
  @JoinTable(name = "Paper_Ref", joinColumns = { @JoinColumn(name = "SrcID") }, inverseJoinColumns = { @JoinColumn(name = "DstID") })
  private Set<Paper> references = new HashSet<Paper>();
}

@Entity
@Table(name = "Paper_Ref")
public class PaperRef
{
  @Id
  private Long id;

  @Column(name = "SrcID")
  private Long srcId;

  @Column(name = "DstID")
  private Long dstId;
}

如您所见,一篇论文链接到其他几篇论文,并且相应的关系存储在名为 Paper_Ref 的表中。 SrcID 和 DstID 对 Paper 的主键具有外键性质。但寻址的主键不一定存在于我的数据库中。

整个工作正常,但如果数据中存在一些不一致(例如,在添加相应论文之前添加论文参考),我会遇到外键约束违规。此外,我真的无法手动控制这些不一致,因为我从另一个没有任何限制的来源接收数据。

通常这就是每个人都希望这种关系发挥作用的方式,但我正在寻找一种方法来避免违规或忽略它。例如通过手动删除约束。

我自己的解决方法是形成一个原生查询,如下所示:

SELECT p FROM Paper AS p WHERE p.id IN (SELECT pr.dstId FROM PaperRef pr WHERE srcId = :id)

但我最好使用原生休眠解决方案,我可以在不使用自制查询的情况下为我的论文集调用 getter。

是否有任何方法可以删除/禁用外键约束或解决此问题的其他方法?还是我对hibernate中的关系如何工作的误解?

提前致谢!

【问题讨论】:

  • 您是否在插入 Paper-Refs 的同时插入论文?
  • PaperRef 是干什么用的? Hibernate 能够自己创建连接表。
  • @SpaceTrucker 不是同时,但我想在受影响的论文之前插入论文参考(如前所述,我从外部来源获取数据)。 Thomas 我通过外部服务获得了这种格式。没有办法操纵它。 SrcID 和 DstID 都是 Paper 中 id 的外键。
  • 但还是有问题。将尚未收到论文的论文参考存储在其他地方,然后在论文导入时将其插入。
  • 是的,我知道这听起来很奇怪。甚至外部服务中的 Paper-Refs 永远不会有真正的 Paper-entity,即使它们引用了某种主键。由于我不知道的原因,外部服务缺少一些文件。所以我只想得到我能得到的东西,剩下的就不管了,因为没有外键。我做了一些操作后,数据库立即被清除,它只用于那个单一的目的。当然,您永远不会想到关闭约束检查,但在我的特殊情况下,这是一个合适的解决方案。

标签: java hibernate jpa foreign-keys hsqldb


【解决方案1】:

我想我现在确实解决了问题。感谢所有读者和贡献者。 HSQLDB 提供了在运行时禁用外键检查的选项。 SQL 语句如下:

SET DATABASE REFERENTIAL INTEGRITY FALSE;

关闭此功能还有另一个后果,这在HSQLDB Docs 中也有说明。 Hibernate 不再跟踪在数据库中所做的更改,因此如果没有进一步的操作,将为关系(子选择)返回不完整的结果。要解决此问题,必须为每个可能已分离的对象调用EntityManager.refresh()

我只是使用内存数据库来获得连接功能,因为外部服务不提供这样的功能。之后我删除了实体,所以这对我来说不是一个大缺点。

编码愉快!

【讨论】:

  • 但这会影响整个数据库,这可能会对应用程序的其他部分产生负面影响。
猜你喜欢
  • 1970-01-01
  • 2013-03-03
  • 2015-11-16
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
  • 2019-04-29
  • 1970-01-01
  • 2020-08-12
相关资源
最近更新 更多