这个 问题困扰我10多天,终于干掉了。
本人使用myeclipse6.5ga,进行hibernate一对多单向关联实例。
一直报如下异常:
Hibernate: insert into hbql.score (score, type) values。。。。。。。。。。。。。。。。。。。17:03:32,484 DEBUG JDBCExceptionReporter:69 - could not insert: [score.Score] [insert into hbql.score (score, type) values (?, ?)]java.sql.SQLException: Field 'sid' doesn't have a default value at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055)..................//太长发不了。省略点17:03:32,484 WARN JDBCExceptionReporter:77 - SQL Error: 1364, SQLState: HY00017:03:32,484 ERROR JDBCExceptionReporter:78 - Field 'sid' doesn't have a default value保存对象student.Student失败!17:03:32,484 DEBUG JDBCTransaction:152 - rollbackorg.hibernate.exception.GenericJDBCException: could not insert: [score.Score] at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:103) at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:91) ...........................//太长发不了。省略点Caused by: java.sql.SQLException: Field 'sid' doesn't have a default value at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055)
测试程序如下:
Student student=new Student("huizhi","2708",200);Score score1=new Score(98,"1");Score score2=new Score(90,"2");Set set=new HashSet();set.add(score1);set.add(score2);student.setScores(set);saveObject(student);printStudents();----------------------------------------------------------------------------------------------------------------------
映射文件Student.hbm.xml
----------------------------------------------------------------------------------------------------------------
映射文件Score.hbm.xml
---------------------------------------------------------------------------------------------------------------------
持久化类
public class Score implements java.io.Serializable { private Integer id; private Integer score; private String type; …..public class Student implements java.io.Serializable { private Integer id; private String name; private String number; private Integer classid; private Set scores=new HashSet(); ….---------------------------------------------------------------------------------------------------------------------
数据库表MySQL
DROP TABLE IF EXISTS `hbql`.`student`;CREATE TABLE `hbql`.`student` ( `id` int(10) unsigned NOT NULL auto_increment, `name` varchar(20) NOT NULL, `number` varchar(20) NOT NULL, `classid` int(10) unsigned NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;DROP TABLE IF EXISTS `hbql`.`score`;CREATE TABLE `hbql`.`score` ( `id` int(10) unsigned NOT NULL auto_increment, `score` int(10) unsigned NOT NULL, `type` varchar(20) NOT NULL, `sid` int(10) unsigned NOT NULL, PRIMARY KEY (`id`), KEY `FK_score_1` (`sid`), CONSTRAINT `FK_score_1` FOREIGN KEY (`sid`) REFERENCES `student` (`id`) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
能解决此问题主要得益于该BLOG:http://suhaoyuan.spaces.live.com/Blog/cns!2659D3AC8253C554!217.entry上的如下一段话。
“
留意元素中的inverse属性,该属性表示关联关系由主控(一方)还是受控方(多方)维护。所谓关联关系的维护就是受控方的外键插入由谁来控制。inverse默认为false,表示由主控方来控制。当主控方控制时,插入SQL的语句会分两条进行
insert into Items(itemName, itemPrice, orderId) values(‘aa’, ‘5.95’, NULL);
update Items set rderId = 3 where itemName = ‘aa’ and itemPrice = ‘5.95’;
因为主控方控制关联关系,意味受控方在插入数据时,不会考虑其外键引用,直接插入为NULL,直到主控方执行更新操作。
”
因为HIbernate分两条SQL语句插入Score对象。所以在SCORE表中,第一次外键为空。所以定义数据库中外键时默认值应为NULL. 第二次是更新该条记录的外键。本人在创建SCORE表外键SID默认是不能为空。所以会出现此种情况,更改为NULL一切正常。
如下为HIbernate生成的SQL语句:
部分。
Hibernate: insert into hbql.score (score, type) values (?, ?)Hibernate: update hbql.score set sid=? where id=?
平平淡淡才是真