Hibernate:双向一对多外键约束失败
我想使用 Hibernate (在 Java 中)实现一对多关系。我有两个实体:
- 实验
- ExperimentGroup
Experiment
有许多 ExperimentGroups
。我尝试按照 Hibernate 官方文档推荐的方式配置这种一对多关系: http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/example-parentchild.html#example-parentchild-cascades
我的配置文件:
<class name="ExperimentImpl" table="Experiment">
<id name="id" type="int" column="id">
<generator class="increment" />
</id>
<!-- One to Many -->
<set name="experimentGroups" table="ExperimentGroup"
lazy="false" fetch="select" cascade="all" inverse="true">
<key>
<column name="Experiment_id" not-null="true" />
</key>
<one-to-many class="ExperimentGroupImpl" />
</set>
</class>
<class name="ExperimentGroupImpl" table="ExperimentGroup">
<id name="id" type="int" column="id">
<generator class="increment" />
</id>
<many-to-one name="experiment" class="ExperimentImpl" fetch="select">
<column name="Experiment_id" not-null="true" />
</many-to-one>
</class>
添加一个新的 < code>ExperimentGroup 到 Experiment
工作正常,但删除实验(及其所有实验组)会导致异常:
无法删除或更新父行:外键约束失败 (
testdb
.ExperimentGroup
,约束FK9C71D86238B5500C
国外 关键(Experiment_id
)参考实验
(id
))
我的 ExperimentDAO 代码如下所示:
public void deleteExperiment(Experiment experiment)
throws DAOException
{
Session session = null;
Transaction t = null;
try{
session = HibernateUtil.getSessionFactory().openSession();
t = session.beginTransaction();
session.delete(experiment);
t.commit();
session.flush();
session.close();
}catch (HibernateException e)
{
e.printStackTrace();
if (t != null)
t.rollback();
if (session != null)
session.close();
throw new DAOException(e, "Could not delete Experiment");
}
}
编辑: 用于创建实验和实验组的 DAO 代码:
public Experiment createExperiment(String name, String description, RegisteredUser owner)
{
Transaction tx = null;
Session session = null;
try
{
session = HibernateUtil.getSessionFactory().openSession();
tx= session.beginTransaction();
ExperimentImpl e = new ExperimentImpl();
e.setName(name);
e.setDescription(description);
e.setOwner(owner);
owner.getOwnedExperiments().add(e);
session.save(e);
tx.commit();
session.flush();
session.close();
return e;
} catch (HibernateException ex )
{
if (tx != null)
tx.rollback();
if (session!=null)
session.close();
throw ex;
}
}
public ExperimentGroup createAndAddExperimentGroup(Experiment experiment, String experimentGroupName, Date startDate, Date endDate) throws ArgumentException
{
Transaction t = null;
Session session = null;
try
{
session = HibernateUtil.getSessionFactory().openSession();
t = session.beginTransaction();
ExperimentGroupImpl g = new ExperimentGroupImpl();
g.setEndDate(endDate);
g.setStartDate(startDate);
g.setName(experimentGroupName);
g.setExperiment(experiment);
experiment.getExperimentGroups().add(g);
g.setExperiment(experiment);
session.save(g);
session.update(experiment);
t.commit();
session.flush();
session.close();
return g;
}catch(HibernateException e)
{
if (t!=null)
t.rollback();
if (session!= null)
session.close();
throw e;
}
}
实验还有许多其他属性,例如名称、描述等,我已将其从配置文件中删除,因为它们不会对一对一产生影响。很多关系。
有什么建议吗?我做错了什么?
I want to implement a one-to-many relation using Hibernate (in Java). I have two entities:
- Experiment
- ExperimentGroup
Experiment
has many ExperimentGroups
. I tried to configure this one-to-many relation, the way the official Hibernate document recommends: http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/example-parentchild.html#example-parentchild-cascades
My config file:
<class name="ExperimentImpl" table="Experiment">
<id name="id" type="int" column="id">
<generator class="increment" />
</id>
<!-- One to Many -->
<set name="experimentGroups" table="ExperimentGroup"
lazy="false" fetch="select" cascade="all" inverse="true">
<key>
<column name="Experiment_id" not-null="true" />
</key>
<one-to-many class="ExperimentGroupImpl" />
</set>
</class>
<class name="ExperimentGroupImpl" table="ExperimentGroup">
<id name="id" type="int" column="id">
<generator class="increment" />
</id>
<many-to-one name="experiment" class="ExperimentImpl" fetch="select">
<column name="Experiment_id" not-null="true" />
</many-to-one>
</class>
Adding a new ExperimentGroup
to an Experiment
works fine, but deleting an Experiment (and all of its ExperimentGroups) causes an exception:
Cannot delete or update a parent row: a foreign key constraint fails
(testdb
.ExperimentGroup
, CONSTRAINTFK9C71D86238B5500C
FOREIGN
KEY (Experiment_id
) REFERENCESExperiment
(id
))
My ExperimentDAO code looks like this:
public void deleteExperiment(Experiment experiment)
throws DAOException
{
Session session = null;
Transaction t = null;
try{
session = HibernateUtil.getSessionFactory().openSession();
t = session.beginTransaction();
session.delete(experiment);
t.commit();
session.flush();
session.close();
}catch (HibernateException e)
{
e.printStackTrace();
if (t != null)
t.rollback();
if (session != null)
session.close();
throw new DAOException(e, "Could not delete Experiment");
}
}
EDIT:
The DAO code to create an Experiment and ExperimentGroup:
public Experiment createExperiment(String name, String description, RegisteredUser owner)
{
Transaction tx = null;
Session session = null;
try
{
session = HibernateUtil.getSessionFactory().openSession();
tx= session.beginTransaction();
ExperimentImpl e = new ExperimentImpl();
e.setName(name);
e.setDescription(description);
e.setOwner(owner);
owner.getOwnedExperiments().add(e);
session.save(e);
tx.commit();
session.flush();
session.close();
return e;
} catch (HibernateException ex )
{
if (tx != null)
tx.rollback();
if (session!=null)
session.close();
throw ex;
}
}
public ExperimentGroup createAndAddExperimentGroup(Experiment experiment, String experimentGroupName, Date startDate, Date endDate) throws ArgumentException
{
Transaction t = null;
Session session = null;
try
{
session = HibernateUtil.getSessionFactory().openSession();
t = session.beginTransaction();
ExperimentGroupImpl g = new ExperimentGroupImpl();
g.setEndDate(endDate);
g.setStartDate(startDate);
g.setName(experimentGroupName);
g.setExperiment(experiment);
experiment.getExperimentGroups().add(g);
g.setExperiment(experiment);
session.save(g);
session.update(experiment);
t.commit();
session.flush();
session.close();
return g;
}catch(HibernateException e)
{
if (t!=null)
t.rollback();
if (session!= null)
session.close();
throw e;
}
}
There are many other properties for an Experiment, like the name, description etc., which I have removed from the config file, because they don't have an impact on the one-to-many relation.
Any suggestion? What did I wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

我的印象是您正在尝试删除手动创建的分离实体。我会尝试使用要删除的实验的主键,并在实际删除之前加载:
I am under the impression that you are trying to delete a detached entity that you manually created. I would try to use the primary key of the Experiment you want to delete, and load before actually deleting it: