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自增列保存失败的问题,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。