我正在研究我的数据库模型问题一段时间了。我使用 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)
但我更喜欢使用原生的hibernate解决方案,我可以在不使用自制查询的情况下为我的论文集调用getter。
有没有办法删除/禁用外键约束或另一种方法来解决这个问题?或者是对我的休眠关系如何工作的误解呢?
提前致谢!
答案 0 :(得分:0)
我想我现在确实解决了这个问题。感谢所有读者和贡献者。 HSQLDB 提供了在运行时禁用外键检查的选项。 SQL语句如下:
SET DATABASE REFERENTIAL INTEGRITY FALSE;
关闭此功能还有其他后果,HSQLDB Docs中也有注明。 Hibernate不再跟踪数据库所做的更改,因此如果没有进一步的操作,将返回关系(Subselects)的不完整结果。要解决此问题,必须为可能已分离的每个对象调用EntityManager.refresh()
!
我只是使用内存数据库来获取连接功能,因为外部服务没有提供这样的功能。我之后删除了实体,所以对我来说这不是一个大缺点。
快乐的编码!