Hibernate/H2 @OneToMany 删除子时“违反参照完整性约束”?
Posted
技术标签:
【中文标题】Hibernate/H2 @OneToMany 删除子时“违反参照完整性约束”?【英文标题】:Hibernate/H2 @OneToMany "Referential integrity constraint violation" on remove of child? 【发布时间】:2015-09-10 11:52:08 【问题描述】:你好,我有一个相当简单的关系。 一个患者可以有多个测量值。我使用了 H2 文件数据库和 Hibernate。
问题: 当我尝试从患者身上删除测量值时,我收到以下错误。
Referential integrity constraint violation: "FK_O423U89KR6K78NNG1PO0ISDF6: PUBLIC.PATIENTVO_MEASUREMENTVO FOREIGN KEY(MEASUREMENTS_ID) REFERENCES PUBLIC.MEASUREMENTVO(ID) (X'3c2b9ee868f645c5a5a743c2a409ab5e')"; SQL statement:
delete from MeasurementVO where id=? [23503-185]
关系中的患者部分:
@OneToMany(orphanRemoval=true, cascade=CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.MERGE, mappedBy = "patient", fetch = FetchType.EAGER)
public List<MeasurementVO> getMeasurements()
return measurements;
关系的测量部分:
@ManyToOne
@JoinColumn
public PatientVO getPatient()
return patient.get();
应该删除测量的函数:
@Override
@Transactional
public boolean removeMeasurementFromPatient(PatientVO patientVO, MeasurementVO measurementVO)
EntityManager manager = emProvider.get();
PatientVO patientAlreadyInDB = manager.find(PatientVO.class, patientVO.getPatientId());
if (patientAlreadyInDB != null)
patientAlreadyInDB.getMeasurements().removeIf(measurement -> measurement.getId().equals(measurementVO.getId()));
manager.merge(patientAlreadyInDB);
return true;
else
return false;
还有持久性 XML:
<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
<persistence-unit name="db" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>ch.fhnw.ima.doggait.vo.PatientVO</class>
<class>ch.fhnw.ima.doggait.vo.MeasurementVO</class>
<class>ch.fhnw.ima.doggait.vo.MeasurementAttributesVO</class>
<class>ch.fhnw.ima.doggait.vo.TimeMark</class>
<properties>
<property name="connection.driver_class" value="org.h2.Driver"/>
<!-- <property name="hibernate.connection.url" value="jdbc:h2:mem:db"/>-->
<property name="hibernate.connection.url" value="jdbc:h2:file:./database/dogdatabase"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<!--<property name="hibernate.hbm2ddl.auto" value="create-drop"/>-->
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.show_sql" value="true"/>
</properties>
</persistence-unit>
</persistence>
是否有人暗示我为什么不能从患者身上删除测量值然后坚持他/她?
【问题讨论】:
【参考方案1】:从违反约束的表的名称 (PATIENTVO_MEASUREMENTVO
) 来看,您似乎有一个中间表来实现该关系。这通常用于多对多关系。
作为一对多关系,为什么不直接将外键从测量添加到患者?
【讨论】:
问题是,我没有手动创建表格。 Hibernate 基于注释创建表。也许我的注释不正确,但这就是我想要找出的。 您可以尝试删除getMeasurements()
的@OneToMany
注释中的mappedBy
属性以及getPatient()
中的@JoinColumn
吗?
谢谢。我之前删除了 JoinColumn 并没有效果。但是删除 JoinColumn 和 mappedBy 就成功了。我现在可以删除测量值。我开始相信有时编写数据库访问类和执行 SQL 查询比使用 ORM 更好。在您遇到一些错误之前,Hibernate 总是很酷。比调试起来更困难,因为你不知道你的表和关系到底是什么样的。至少如果你像我一样是这个领域的菜鸟。以上是关于Hibernate/H2 @OneToMany 删除子时“违反参照完整性约束”?的主要内容,如果未能解决你的问题,请参考以下文章
Spring Hibernate H2 Junit 测试 - 如何在启动时加载模式