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) ...
随机推荐
- Java多线程练习二
public class ex3 { public static void main(String [] args) { thread2 t1 = new thread2("hello&qu ...
- 锚点链接和hash属性
相信大家挺经常见过这样一个效果.有一个很长很长的页面,分成好几部分,目录中一点击,就能定位到页面某个位置. 例如:有这样一个目录,例如你点击一下“HTML”,就会直接跳转到“HTML”的页面位置 这就 ...
- js获得url的参数
网上找的一段代码,非常好用,现在难以找到原作者,但是非常感谢!/** * 获取当前URL参数值 * @param name 参数名称 * @return 参数值 */ function ...
- Markdown 入门教程
Markdown 是一种轻量级的标记语言,轻到你甚至可以不叫他语言,因为 Markdown 很容易上手,就是简单地记住几个常用的标签用法就OK了,Markdown 有诸多好处:专注于文字,简单,高效. ...
- [转载]C++ 堆与栈简单的介绍
在C和C++中,有三种使用存储区的基本方式: [静态存储区(Static Memory)] 在静态存储区中,连接器(linker)根据程序的需求为对象分配空间.全局变量.静态类成员以及函数中的静态 ...
- Objective-C中的copy协议
NSObject对象是否可以copy自己 NSObject类没有实现NSCopying或者NSMutableCopying协议,但是却有copy以及mutableCopy实例方法.然而,如果用NSOb ...
- memcached学习笔记——存储命令源码分析上篇
原创文章,转载请标明,谢谢. 上一篇分析过memcached的连接模型,了解memcached是如何高效处理客户端连接,这一篇分析memcached源码中的process_update_command ...
- Symfony2之创建一个简单的web应用
Symfony2——创建bundle bundle就像插件或者一个功能齐全的应用,我们在应用层上开发的应用的所有代码,包括:PHP文件.配置文件.图片.css文件.js文件等都会包含在bu ...
- 文件操作IO流
fopen 打开文件或者生成文件 getc 向文件中读取一个字符 putc 向文件中写入一个字符 fgets 向文件中读取字符串 参数可以设置获取多少个字符串 fputs 向文件中写入字符串 不自动添 ...
- 磁珠(FB)的选用
1. 磁珠(FB)的单位是欧姆,而不是亨特,这一点要特别注意.因为磁珠的单位是按照它在某一频率 产生的阻抗来标称的,阻抗的单位也是欧姆.磁珠的 DATASHEET上一般会提供频率和阻抗的特性曲线图,一 ...