本人使用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: HY000
17:03:32,484 ERROR JDBCExceptionReporter:78 - Field 'sid' doesn't have a default value
保存对象student.Student失败!
17:03:32,484 DEBUG JDBCTransaction:152 - rollback
org.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;
---------------------------------------------------------------------------------------------------------------------
留意元素中的inverse属性,该属性表示关联关系由主控(一方)还是受控方(多方)维护。所谓关联关系的维护就是受控方的外键插入由谁来控制。inverse默认为false,表示由主控方来控制。当主控方控制时,插入SQL的语句会分两条进行
insert into Items(itemName, itemPrice, orderId) values('aa', '5.95', NULL);
update Items set orderId = 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=?