Hibernate自增列保存失败的问题

author: hiu

最近由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() {
<span style="white-space:pre">	</span>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;
	}

	<strong>@Id
	@GeneratedValue(strategy = IDENTITY)</strong>
	@Column(name = "id", unique = true, nullable = false)
	public Integer getId() {
		return this.id;
	}

	public void setId(Integer id) {
		this.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插入,而是在数据库中自动增加了。

总结:注解地方的错误是因为使用myEclipse生成实体类时引致的注解设置地方错误,所以有时也不要太过依赖自动生成实体类。个人猜测原因,是因为我将id设为是自增的,但keyjobno列设置为主键,也即是说,这两列都是唯一的,myEclipse在生成实体类是可能不能区分,就将自增列的注解设置了在主键的列上了,没仔细研究,大家有兴趣的话,可以去研究下。

Hibernate自增列保存失败的问题,布布扣,bubuko.com

时间: 2024-08-05 23:09:32

Hibernate自增列保存失败的问题的相关文章

Hibernate一对多关联关系保存时的探究

在以前使用hibernate时,经常对保存存在关联关系的对象时,不确定是否能保存成功.    因此,特意对一对多关系的2个对象进行实践. 一.pojo类和配置文件的准备 这里有一点提前说一下,外键列在数据库中并没有设置为不为null.因此可以出现外键为空的情况. (1)pojo类     (2)映射文件      (3)测试类中方法的准备 二.双方都维护关联关系且双向关联 注意:这里的双向关联是指双向都建立关系 (1)1方和多方都保存,且建立了双向关联的关系.这样是肯定可以保存成功的. (2)1

hibernate常用增删改查接口实现

1 /** 2 * 作者:宫长明 3 * 4 */ 5 6 7 import java.io.Serializable; 8 import java.util.List; 9 import java.util.Map; 10 11 import org.hibernate.criterion.Criterion; 12 import org.hibernate.criterion.DetachedCriteria; 13 14 @SuppressWarnings("unchecked"

mysql 清空或删除表数据后,控制表自增列值的方法

http://blog.sina.com.cn/s/blog_68431a3b0100y04v.html 方法1: truncate table 你的表名 //这样不但将数据全部删除,而且重新定位自增的字段 方法2: delete from 你的表名 dbcc checkident(你的表名,reseed,0) //重新定位自增的字段,让它从1开始 方法3: 如果你要保存你的数据,介绍你第三种方法,by QINYI 用phpmyadmin导出数据库,你在里面会有发现哦 编辑sql文件,将其中的自

hibernate第一个例子-保存对象

3.hibernate第一个例子-保存对象 使用hibernate框架需要导入的jar包: antlr-2.7.6 backport-util-concurrent c3p0-0.9.1 commons-collections-3.1    apache集合帮助的包 commons-logging-1.1.1日志 dom4j-1.6.1解析XML ehcache-1.5.0缓存框架 hibernate3hibernate核心包 javassist-3.9.0.GA代理模式工具包,解决懒加载问题

MySQL使用AUTO_INCREMENT列的表注意事项之update自增列篇

1. 说明 (1)对于MyISAM表,如果用UPDATE更新自增列,如果列值与已有的值重复,则会出错:如果大于已有的最大值,则会自动更新表的AUTO_INCREMENT,操作是安全的. (2)对于innodb表,update auto_increment字段,如果列值与已有的值重复,则会出错:如果大于已有的最大值,可能会引入一个坑,会造成编号重复错误,插入数据失败的情况,可见在update自增列值是要注意. 环境描述:RHEL 6.4 x86_64 + MySQL 5.6.19 blog地址:h

MySQL自增列的步长问题

唯一索引和联合唯一 外键的变种 SQL数据行的增删改查 视图 触发器 函数 存储过程 事务 游标 动态执行SQL(防SQL注入) 1.MySQL自增列的步长问题: 1.基于会话级别(单次登陆状态下): show session variables like 'auto_inc%';    #查看自增长的默认步数,一般为1 set session auto_increment_increment=2;    #设置自增长会话步长为2 set session auto_increment_offse

mysql中InnoDB表为什么要建议用自增列做主键

InnoDB引擎表的特点 1.InnoDB引擎表是基于B+树的索引组织表(IOT) 关于B+树 (图片来源于网上) B+ 树的特点: (1)所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好是有序的; (2)不可能在非叶子结点命中; (3)非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储(关键字)数据的数据层; 2.如果我们定义了主键(PRIMARY KEY),那么InnoDB会选择主键作为聚集索引.如果没有显式定义主键,则InnoDB会选择第一个不包含有NU

程矢Oracle PowerDesigner中生成Oracle版本主键和自增列

Oracle中如何新建自增列,总的来说需要建立序列,并把这个序列付给某一列,重建触发器即可. 第一步,打开PD,新建一个PDM文档,然后新建一个表,如图所示: 第二步,创建一个序列.在[Model]-[Sequence]打开序列列表窗口,新建一个序列.然后打开序列的属性设置项[physical Options],进行如下设置,点击确定,序列建立完毕. 第三步,将刚刚创建的序列应用到表的主键列中,如图所示:点击确定, 点击确定,至此,自动创建了一个触发器,把序列的值添加到主键中.

innodb 自增列重复值问题

1 innodb 自增列出现重复值的问题 先从问题入手,重现下这个bug use test; drop table t1; create table t1(id int auto_increment, a int, primary key (id)) engine=innodb; insert into t1 values (1,2);insert into t1 values (null,2); insert into t1 values (null,2); select * from t1;