Hibernate自增列保存失败的问题
author: hiu
更正说明:今天(2014-07-07)才发现的问题,我把@Id设置在了实体类中的id中,@Id是主键,应该设置在实体类的keyjobno中,之前发的文章可能误导了大家,如今更正一下,请看以下红色的更正内容。
近期由ibatis转用Hibernate,期间遇到了一系列的问题,今天又遇到了个问题,是由于自增列的问题导致保存时报错,如今记录下来,以便日后忘记时查看
这个问题事实上是使用myEclipse生成表的实体类时,自增列的注解错误导致的。
问题原因:利用myEclipse的Hibernate Reverse Engineening生成的实体类自增列注解设置了在主键keyjobno上,而不是相应的 id 列上
解决的方法 :将自增列注解设置在相应的 自增列id上
数据库employee表:
这里主要列出了部分字段,关键在于id和keyjobno,id设置了是自增列,keyjobno设置为主键
利用myEclipse的Hibernate Reverse Engineening生成实体类
生成后的实体类Employee,仅仅贴出了keyjobno,id的,其他的没贴出来
@Entity
@Table(name = "employee", catalog = "union_ssh", uniqueConstraints = @UniqueConstraint(columnNames = "id"))
public class Employee implements java.io.Serializable { // Fields private String keyjobno;
private Integer id; @Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "keyjobno", unique = true, nullable = false, length = 20)
public String getKeyjobno() {
return this.keyjobno;
} public void setKeyjobno(String keyjobno) {
this.keyjobno = keyjobno;
} @Column(name = "id", unique = true, nullable = false)
public Integer getId() {
return this.id;
} public void setId(Integer id) {
this.id = id;
}
}
service层
public Employee save(Employee employee) throws SQLException { employee.setKeyjobno("K8888"); employeeDao.save(employee); return employee;
}
dao层
@Override
public Serializable save(T o) {
return this.getCurrentSession().save(o);
}
控制台打印出的sql语句:
2014-07-04 14:10:50 [org.hibernate.SQL]-[DEBUG]
insert
into
union_ssh.employee
(born_boon, borndate, company, createdate, dept, getborn_date, getmarry_date, id, identitycard, ifout, interest, jobno, lodging, marry, marry_boon, name, nativename, operator, phone, politicsface, sex)
values
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate:
insert
into
union_ssh.employee
(born_boon, borndate, company, createdate, dept, getborn_date, getmarry_date, id, identitycard, ifout, interest, jobno, lodging, marry, marry_boon, name, nativename, operator, phone, politicsface, sex)
values
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2014-07-04 14:10:50 [org.hibernate.engine.jdbc.spi.SqlExceptionHelper]-[DEBUG] Field 'keyjobno' doesn't have a default value [n/a]
<span style="color:#ff0000;"><strong>java.sql.SQLException: Field 'keyjobno' doesn't have a default value</strong></span>
注意红色部分了,报错说我keyjobno没有默认值,最奇怪的就是这里了,我明明在service层里设置了
employee.setKeyjobno("K8888");
明明已经为keyjobno设置值了,竟然还说我没有默认值。再看一下打出来的sql语句,里面有id,可是没有keyjobno,按理说id在数据库表中设置了自增,这里不应该也插入的,但keyjobno明明是已经设置了值的,却没有显示在插入的sql中,这是由于注解时将keyjobno设置为了自增列了。
如今再来看看实体类中的注解:
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "keyjobno", unique = true, nullable = false, length = 20)
public String getKeyjobno() {
return this.keyjobno;
}
注解意思:
@Id —— 注解声明了该实体bean的标识属性(相应表中的主键)。
@GeneratedValue —— 注解声明了主键的生成策略。该注解有例如以下属性
strategy
指定生成的策略(JPA定义的),这是一个GenerationType。默认是GenerationType. AUTO
GenerationType.AUTO 主键由程序控制
GenerationType.IDENTITY
主键由数据库自己主动生成(主要是自己主动增长类型)
看到注讲解明,大家应该就明确了,我在数据库表中设置的是id自增列,可是生成的实体类的自增列却是keyjobno,这就是导致保存失败的原因了,将实体类改为下面形式,主要是将keyjobno的自增注解剪切到id列中
@Entity
@Table(name = "employee", catalog = "union_ssh", uniqueConstraints = @UniqueConstraint(columnNames = "id"))
public class Employee implements java.io.Serializable { private String keyjobno;
private Integer id; @Column(name = "keyjobno", unique = true, nullable = false, length = 20)
public String getKeyjobno() {
return this.keyjobno;
} public void setKeyjobno(String keyjobno) {
this.keyjobno = keyjobno;
} @Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", unique = true, nullable = false)
public Integer getId() {
return this.id;
} public void setId(Integer id) {
this.id = id;
}
}
@Id设置了在id属性的get方法中,去掉这里的@Id,由于@Id是代表主键,能够看到上面数据库employee表中的图,keyjobno才是主键,所以应该把@Id设置在keyjobno的get方法上才对
@Id
@Column(name = "keyjobno", unique = true, nullable = false, length = 20)
public String getKeyjobno() {
return this.keyjobno;
}
假设你不更正这里,在做employee表的单独插入操作时是没问题的,假设你有其他表关联了employee表的keyjobno主键,但你没有将@Id设置在keyjobno上,那么这里问题就来了,假设你往关联的表中插入数据时,就无法插入了,由于关联的表相应不了employee的主键,导致无法插入。我今天用in_union_his表关联了employee表,在做in_union_his表插入操作时,不断提示外键约束失败,无法往子表in_union_his中插入数据
,以下是我今天操作时失败的错误信息:Cannot add or update a child row: a foreign key constraint fails
2014-07-07 10:03:18 [org.hibernate.SQL]-[DEBUG]
insert
into
union_ssh.employee
(bornboon, borndate, company, createdate, dept, getborndate, getmarrydate, identitycard, ifout, interest, jobno, keyjobno, lodging, marry, marryboon, name, nativename, operator, phone, politicsface, sex)
values
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate:
insert
into
union_ssh.employee
(bornboon, borndate, company, createdate, dept, getborndate, getmarrydate, identitycard, ifout, interest, jobno, keyjobno, lodging, marry, marryboon, name, nativename, operator, phone, politicsface, sex)
values
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2014-07-07 10:03:18 [org.hibernate.id.IdentifierGeneratorHelper]-[DEBUG] Natively generated identity: 660
2014-07-07 10:03:18 [org.hibernate.engine.spi.ActionQueue]-[DEBUG] Executing identity-insert immediately
2014-07-07 10:03:18 [org.hibernate.SQL]-[DEBUG]
insert
into
union_ssh.in_union_his
(createdate, keyjobno, inuniondate, operator)
values
(?, ?, ?, ?)
Hibernate:
insert
into
union_ssh.in_union_his
(createdate, keyjobno, inuniondate, operator)
values
(?, ?, ?, ?)
2014-07-07 10:03:18 [org.hibernate.engine.jdbc.spi.SqlExceptionHelper]-[DEBUG]Cannot add or update a child row: a foreign key constraint fails (`union_ssh`.`in_union_his`, CONSTRAINT `FK_in_union_his` FOREIGN KEY (`keyjobno`) REFERENCES `employee` (`keyjobno`) ON DELETE CASCADE ON UPDATE CASCADE) [n/a]
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`union_ssh`.`in_union_his`, CONSTRAINT `FK_in_union_his` FOREIGN KEY (`keyjobno`) REFERENCES `employee` (`keyjobno`) ON DELETE CASCADE ON UPDATE CASCADE)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
仅仅要将@Id设在数据库表主键相应的实体类的属性keyjobno上,就攻克了,关键是我之前把@Id设置在了id属性上。
又一次部署,再运行保存,控制台打印出来的sql语句:
2014-07-04 14:30:21 [org.hibernate.SQL]-[DEBUG]
insert
into
union_ssh.employee
(born_boon, borndate, company, createdate, dept, getborn_date, getmarry_date, identitycard, ifout, interest, jobno, keyjobno, lodging, marry, marry_boon, name, nativename, operator, phone, politicsface, sex)
values
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate:
insert
into
union_ssh.employee
(born_boon, borndate, company, createdate, dept, getborn_date, getmarry_date, identitycard, ifout, interest, jobno, keyjobno, lodging, marry, marry_boon, name, nativename, operator, phone, politicsface, sex)
values
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2014-07-04 14:30:21 [org.hibernate.id.IdentifierGeneratorHelper]-[DEBUG] Natively generated identity: 557
最后 一行Natively generated identity: 557这句是什么意思呢,事实上557就是插入的这条记录的id了,由于我数据库中已经有556记录了,这就说明保存成功了,大家能够看到,这条sql语句已经没有id存了,也即是说sql语句插入时没有把id插入,而是在数据库中自己主动添加�了。今天(2014-07-07)再经过測试,发现,这里显示不显示id出来都能够插入成功,不显示的原因是由于我之前把注解@Id,@GeneratedValue(strategy
= IDENTITY)设在了id列中才没显示出来,我预计是仅仅要你注解设置在自增列而且自增列是主键时,就在插入时sql语句不显示这个列了
总结:注解地方的错误是由于使用myEclipse生成实体类时引致的注解设置地方错误,所以有时也不要太过依赖自己主动生成实体类。个人推測原因,是由于我将id设为是自增的,但keyjobno列设置为主键,也即是说,这两列都是唯一的,myEclipse在生成实体类是可能不能区分,就将自增列的注解设置了在主键的列上了,没细致研究,大家有兴趣的话,能够去研究下。
Hibernate自增列保存失败的问题的更多相关文章
- Hibernate一对多关联关系保存时的探究
在以前使用hibernate时,经常对保存存在关联关系的对象时,不确定是否能保存成功. 因此,特意对一对多关系的2个对象进行实践. 一.pojo类和配置文件的准备 这里有一点提前 ...
- MySQL--更新自增列的潜在风险
##=====================================================================##测试环境:MySQL版本:MySQL 5.7.19复制 ...
- MySQL使用AUTO_INCREMENT列的表注意事项之update自增列篇
1)对于MyISAM表,如果用UPDATE更新自增列,如果列值与已有的值重复,则会出错:如果大于已有的最大值,则会自动更新表的AUTO_INCREMENT,操作是安全的. (2)对于innodb表,u ...
- mysql 清空或删除表数据后,控制表自增列值的方法
http://blog.sina.com.cn/s/blog_68431a3b0100y04v.html 方法1: truncate table 你的表名 //这样不但将数据全部删除,而且重新定位自增 ...
- mysql 深度解析auto-increment自增列"Duliplicate key"问题
转载自:https://cloud.tencent.com/developer/article/1367681 问题描述 近期,线上有个重要Mysql客户的表在从5.6升级到5.7后master上插入 ...
- innodb 自增列重复值问题
1 innodb 自增列出现重复值的问题 先从问题入手,重现下这个bug use test; drop table t1; create table t1(id int auto_increment, ...
- SQL Server数据库sql语句生成器(SqlDataToScript)的使用(sql server自增列(id)插入固定值)
SqlDataToScript是根据表数据进行生成 Insert Into语句,此工具还有一个好处是可以对自增列插入固定值,例如:自增的列id值为5,但是5这个行值已经删除,如果想存储Id自增列值为5 ...
- SQL Server 2008 R2——使用计算列为表创建自定义的自增列
=================================版权声明================================= 版权声明:原创文章 谢绝转载 请通过右侧公告中的“联系邮 ...
- mysql中,通过脚本设置表的自增列,及自增步长
设置自增列(其实通过navicate可以直接设置的,也方便:要不然可能需要删除列了) ALTER TABLE `domain_dns_tucows` CHANGE `id` `id` INT(11) ...
随机推荐
- MySQL 加密/压缩函数
这些问题可能导致数据值的改变.一般而言,上述问题可能在你使用非二进制串数据类型(如char,varchar,text等数据类型)的情况下发生. AES_ENCRYPT()和AES_DECRYPT() ...
- Netmon: A light-weight network monitor for Windows
Netmon is a light-weight network monitor that works on Windows operating systems. It provides differ ...
- UITextField点击return后注销第一响应者
// 当点击了return按钮,就让text调用自己的endEditing方法 [textField addTarget:textField action:@selector(endEditing:) ...
- 部署hibernate框架项目时出现问题:The type java.lang.Object cannot be resolved. It is indirectly referenced from required .class files.
基本情况: (这些其实关系不大)我是直接impor导入HibernateDemo项目到eclipse中的,该项目的hibernate版本是3.6.7.Final版,使用了Hibernate Tools ...
- Oracle之事务
一,oracle的事务: 是指对数据操作的一系列动作的统称.即:事务的任务便是使数据库从一种状态变换成为另一种状态,这不同于文件系统,它是数据库所特用的. 事务有四大特性(ACID): 1,原子性(a ...
- 国外.net学习资源网站
转载 :出处:http://www.cnblogs.com/kingjiong/ 名称:快速入门地址 http://chs.gotdotnet.com/quickstart/ 描述:本站点是微软.NE ...
- OSG多屏显示问题
// testMultiScreen.cpp : Defines the entry point for the console application.// #include "stdaf ...
- mysql中取系统当前时间
<select id="getFreightEfclInventoryList" parameterType="long" resultMap=" ...
- 腾讯的一道js面试题(原型)
有一只小狗叫花花,它会“汪汪”叫,他的同伴也会汪汪叫,后来环境发生了变化,新出生的狗不会再“汪汪”叫,而变成“呜呜”叫. 试通过继承来达到目的 function Dog(){ 2 this.bark ...
- python 各模块
01 关于本书 02 代码约定 03 关于例子 04 如何联系我们 1 核心模块 11 介绍 111 内建函数和异常 112 操作系统接口模块 113 类型支持模块 114 正则表达式 115 语言支 ...