我尽量只说关键的。 
两张表,Information和Attachment,主键都叫DBID_,自增,Attachment里有个information_dbid作为外键,指向Information表。 
很奇怪的是,明明lazy=false,但是有那么几条顽固记录取出来Information会发现Attachment为空,但是数据库里明明是有指向这几条的Attachment.发生这种现象以后,再调用Spring的getHibernateTemplate().save(information)就无法保存成功(information里是有attachment的),配置和抓取到的SQL,HQL如下: DROP TABLE IF EXISTS `datalk`.`information`;
CREATE TABLE  `datalk`.`information` (
  `DBID_` bigint(20) unsigned NOT NULL auto_increment,
  `TITLE` varchar(255) NOT NULL default '',
  `CONTENT` longtext,
  PRIMARY KEY  (`DBID_`)
) ENGINE=InnoDB AUTO_INCREMENT=71 DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `datalk`.`attachment`;
CREATE TABLE  `datalk`.`attachment` (
  `DBID_` bigint(20) unsigned NOT NULL auto_increment,
  `information_dbid` bigint(20) unsigned default NULL,
  `name` varchar(255) NOT NULL default '',
  `content_type` varchar(45) NOT NULL default '',
  `content` longblob,
  PRIMARY KEY  (`DBID_`),
  CONSTRAINT `FK_attachment_1` FOREIGN KEY (`DBID_`) REFERENCES `information` (`DBID_`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; <hibernate-mapping>
    <class name="net.datalk.persist.model.Information" table="information" catalog="datalk">
        <id name="dbid" type="java.lang.Long">
            <column name="DBID_" />
            <generator class="native" />
        </id>        <property name="title" type="java.lang.String">
            <column name="TITLE" not-null="true" />
        </property>
        <property name="content" type="java.lang.String">
            <column name="CONTENT" />
        </property>        <set name="attachments" cascade="all-delete-orphan" inverse="true">
            <key>
                <column name="information_dbid"/>
            </key>
            <one-to-many class="net.datalk.persist.model.Attachment" />
        </set>
    </class>
</hibernate-mapping>  <hibernate-mapping>
    <class name="net.datalk.persist.model.Attachment" table="attachment" catalog="datalk">
        <id name="dbid" type="java.lang.Long">
            <column name="DBID_" />
            <generator class="native" />
        </id>
        <many-to-one name="information" column="information_dbid" class="net.datalk.persist.model.Information" cascade="save-update" not-null="false"> 
        </many-to-one>
        <property name="name" type="java.lang.String">
            <column name="name" not-null="true" />
        </property>
        <property name="contentType" type="java.lang.String">
            <column name="content_type" length="45" not-null="true" />
        </property>
        <property name="content" type="org.springframework.orm.hibernate3.support.BlobByteArrayType">
            <column name="content" />
        </property>
    </class>
</hibernate-mapping>
 平时执行插入的命令是Hibernate: insert into datalk.information (TITLE, CONTENT, SUBMITBY) values (?, ?, ?)
Hibernate: insert into datalk.attachment (information_dbid, name, content_type, content) values (?, ?, ?, ?) 
出问题的时候是:Hibernate: insert into datalk.information (TITLE, CONTENT, SUBMITBY) values (?, ?, ?)
Hibernate: insert into datalk.attachment (information_dbid, name, content_type, content) values (?, ?, ?, ?)2009-9-14 20:54:19 org.hibernate.util.JDBCExceptionReporter logExceptions
警告: SQL Error: 1452, SQLState: 23000 com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`datalk/attachment`, CONSTRAINT `FK_attachment_1` FOREIGN KEY (`DBID_`) REFERENCES `information` (`DBID_`))
大家可以看到,语句没有什么区别,SQL Error 1452我查过了,一般是值有外键约束的子表插入的时候,里面的外键指向的父表记录不存在。而到底是不是不存在呢。我又查阅了Mysql的log,可以看到        2 Query       insert into datalk.information (TITLE, CONTENT, SUBMITBY) values ('fasdfasdf', 'sadfasdfasdf', 'aaa')        2 Query       insert into datalk.attachment (information_dbid, name, content_type, content) values (70, 'log2.txt', 'text/plain', x'7472616E73706')
字表的外键是70,而在插入这条数据之前,MYSQL的Information表里最大主键为69,也就是说本来就该是70,那么为什么会不成功呢?如果没有附件,Information就能插入成功。 程序架构采用了Spring,Hibernate,Spring采用AOP方式管理事务,全部是Innodb

解决方案 »

  1.   

    外键的问题但是楼主这个问题没遇到过,<set name="attachments" cascade="all-delete-orphan" inverse="true">是不是与cascade有关呢?可以配cascade="save-update"试一试
      

  2.   

    我是楼主,cascade全试过了。我最后解决了,居然是不建表,用hibernate自动建表。我对比了下表的区别,唯一的区别居然是在那个外键那列加了个Index,真是无法理喻
      

  3.   


    我们就是用hibernate自动建表的,有时候自动创建的东东确实令人难以理解,只要功能实现了,也就不说那么多了