Java Hibernate:外键约束违反问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/556238/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 16:09:48  来源:igfitidea点击:

Hibernate : Foreign key constraint violation problem

javamysqlhibernatespring

提问by Vinze

I have a com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException in my code (using Hibernate and Spring) and I can't figure why. My entities are Corpus and Semspace and there's a many-to-one relation from Semspace to Corpus as defined in my hibernate mapping configuration :

我的代码中有一个 com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException(使用 Hibernate 和 Spring),我不知道为什么。我的实体是 Corpus 和 Semspace,并且在我的休眠映射配置中定义了从 Semspace 到 Corpus 的多对一关系:

<class name="xxx.entities.Semspace" table="Semspace" lazy="false" batch-size="30">
    <id name="id" column="idSemspace" type="java.lang.Integer" unsaved-value="null">
        <generator class="identity"/>
    </id>
    <property name="name" column="name" type="java.lang.String" not-null="true" unique="true" />
    <many-to-one name="corpus" class="xxx.entities.Corpus" column="idCorpus"
                insert="false" update="false" />
    [...]
</class>
<class name="xxx.entities.Corpus" table="Corpus" lazy="false" batch-size="30">
    <id name="id" column="idCorpus" type="java.lang.Integer" unsaved-value="null">
        <generator class="identity"/>
    </id>
    <property name="name" column="name" type="java.lang.String" not-null="true" unique="true" />
</class>

And the Java code generating the exception is :

生成异常的 Java 代码是:

Corpus corpus = Spring.getCorpusDAO().getCorpusById(corpusId);
Semspace semspace = new Semspace();
semspace.setCorpus(corpus);
semspace.setName(name);
Spring.getSemspaceDAO().save(semspace);

I checked and the corpus variable is not null (so it is in database as retrieved with the DAO) The full exception is :

我检查过,语料库变量不为空(所以它在用 DAO 检索的数据库中)完整的例外是:

com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`xxx/Semspace`, CONSTRAINT `FK4D6019AB6556109` FOREIGN KEY (`idCorpus`) REFERENCES `Corpus` (`idCorpus`))
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:931)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2941)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1623)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1715)
at com.mysql.jdbc.Connection.execSQL(Connection.java:3249)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1268)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1541)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1455)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1440)
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:102)
at org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:73)
at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:33)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2158)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2638)
at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:48)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:250)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:298)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:181)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:107)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:187)
at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:33)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:172)
at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:27)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:535)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:523)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:519)
at org.springframework.orm.hibernate3.HibernateTemplate.doInHibernate(HibernateTemplate.java:642)
at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:373)
at org.springframework.orm.hibernate3.HibernateTemplate.save(HibernateTemplate.java:639)
at xxx.dao.impl.AbstractDAO.save(AbstractDAO.java:26)
at org.apache.jsp.functions.semspaceManagement_jsp._jspService(semspaceManagement_jsp.java:218)
[...]

The foreign key constraint has been created (and added to database) by hibernate and I don't see where the constraint can be violated. The table are innodb and I tried to drop all tables and recreate it the problem remains...

外键约束已由 hibernate 创建(并添加到数据库中),我看不出哪里可以违反约束。该表是 innodb,我尝试删除所有表并重新创建它,问题仍然存在...

EDIT : Well I think I have a start of answer... I change the log level of hibernate to DEBUG and before it crash I have the following log

编辑:嗯,我想我有一个开始的答案......我将休眠的日志级别更改为调试,在崩溃之前我有以下日志

insert into Semspace (name, [...]) values (?, [...])

So it looks like it does not try to insert the idCorpus and as it is not null it uses the default value "0" which does not refers to an existing entry in Corpus table...

所以看起来它没有尝试插入 idCorpus 并且因为它不为空它使用默认值“0”,它不引用语料库表中的现有条目......

采纳答案by jon077

I get confused w/ the association mappings all the time. Review the association needed and the hibernate mapping config used to create the assiocation.

我一直对关联映射感到困惑。查看所需的关联和用于创建关联的休眠映射配置。

http://docs.jboss.org/hibernate/core/3.5/reference/en/html/associations.html

http://docs.jboss.org/hibernate/core/3.5/reference/en/html/associations.html

is a great recipe book of associations.

是一本很棒的联想食谱书。

回答by paxdiablo

Seems simple enough. The first line of your exception clearly states that the violation is from the column idCorpusto another column in another table, Corpus/idCorpus.

看起来很简单。您的异常的第一行明确指出违规是从idCorpus另一个表中的列到另一列Corpus/idCorpus

You should be able to access the database directly to figure out what the constraint is. I suspect it's a simple lookup on the other table.

您应该能够直接访问数据库以找出约束是什么。我怀疑这是对另一个表的简单查找。

Then print out the value that you're using in the supplied Java code and, hopefully, voila, you'll know what value you're trying to insert in Semspace that isn't in Corpus.

然后打印出您在提供的 Java 代码中使用的值,希望瞧,您将知道您尝试在 Semspace 中插入哪些值而不是在 Corpus 中。

com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (diaz/Semspace, CONSTRAINT FK4D6019AB6556109FOREIGN KEY (idCorpus) REFERENCES Corpus(idCorpus))

com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (diaz/Semspace, CONSTRAINT FK4D6019AB6556109FOREIGN KEY (idCorpus) REFERENCES Corpus(idCorpus))

回答by gubby

Old post I know, but I had this and fixed it the end by changing @ManyToMany to @OneToMany if the other side is @ManyToOne.

我知道旧帖子,但如果另一边是@ManyToOne,我有这个并通过将@ManyToMany 更改为@OneToMany 来修复它。

回答by Ryan Shillington

Old post, I know, but I found all of these solutions lacking.

旧帖子,我知道,但我发现所有这些解决方案都缺乏。

In the hibernate mapping, you have:

在休眠映射中,您有:

<many-to-one name="corpus" class="xxx.entities.Corpus" column="idCorpus"
            insert="false" update="false" />

You should change the second line to:

您应该将第二行更改为:

<many-to-one name="corpus" class="xxx.entities.Corpus" column="idCorpus"
            cascade="save-update" not-null="true" insert="true" />