简体   繁体   English

Hibernate:外键约束违规问题

[英]Hibernate : Foreign key constraint violation problem

I have a com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException in my code (using Hibernate and Spring) and I can't figure why. 我的代码中有一个com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException(使用Hibernate和Spring),我无法理解为什么。 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 : 我的实体是Corpus和Semspace,在我的hibernate映射配置中定义了从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$12.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. 外键约束已被hibernate创建(并添加到数据库),我没有看到可以违反约束的位置。 The table are innodb and I tried to drop all tables and recreate it the problem remains... 该表是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 编辑:嗯,我想我有一个开始的答案...我将hibernate的日志级别更改为DEBUG,并在崩溃之前我有以下日志

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,因为它不是null,它使用默认值“0”,它不引用Corpus表中的现有条目...

I get confused w/ the association mappings all the time. 我一直对关联映射感到困惑。 Review the association needed and the hibernate mapping config used to create the assiocation. 查看所需的关联以及用于创建assiocation的hibernate映射配置。

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. 是一个伟大的协会食谱书。

Old post, I know, but I found all of these solutions lacking. 老帖子,我知道,但我发现所有这些解决方案都缺乏。

In the hibernate mapping, you have: 在hibernate映射中,您有:

<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" />

Seems simple enough. 看起来很简单。 The first line of your exception clearly states that the violation is from the column idCorpus to 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中插入的值不在语料库中。

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

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

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

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