简体   繁体   English

休眠:双向一对多外键约束失败

[英]Hibernate: bidirectional one-to-many foreign key constraint fails

I want to implement a one-to-many relation using Hibernate (in Java). 我想使用Hibernate(在Java中)实现一对多关系。 I have two entities: 我有两个实体:

  • Experiment 实验
  • ExperimentGroup ExperimentGroup

Experiment has many ExperimentGroups . Experiment有许多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 我尝试按照官方Hibernate文档建议的方式配置此一对多关系: http : //docs.jboss.org/hibernate/core/3.6/reference/zh-CN/html/example-parentchild.html#例如-父子-级联

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: 将新的ExperimentGroup添加到Experiment可以正常工作,但是删除Experiment(及其所有ExperimentGroup)会导致异常:

Cannot delete or update a parent row: a foreign key constraint fails ( testdb . ExperimentGroup , CONSTRAINT FK9C71D86238B5500C FOREIGN KEY ( Experiment_id ) REFERENCES Experiment ( id )) 无法删除或更新父行,外键约束失败( testdbExperimentGroup ,约束FK9C71D86238B5500C外键( Experiment_id )参考Experimentid ))

My ExperimentDAO code looks like this: 我的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");
        }
    }

EDIT: The DAO code to create an Experiment and ExperimentGroup: 编辑: DAO代码创建一个Experiment和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? 我怎么了

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: 我会尝试使用您要删除的实验的主键,并在实际删除它之前加载:

session = HibernateUtil.getSessionFactory().openSession();
t = session.beginTransaction();
ExperimentImpl persistentExperiment = session.load(ExperimentImpl.class, experiment.getId());
session.delete(persistentExperiment);
t.commit();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM