关于Hibernate修改数据库主键

时间:2021-06-04 07:23:06

最近做数据库的时候,没有设置自动增加的主键。一开始没看出毛病,等做到修改的时候傻眼了!hibernate是根据ID来取出数据,保存也是根据ID。报错了:Batch update returned unexpected row count from update: 0 actual row count: 0 expected: 1。(主键设置为自增长,而在我们插入记录的时候设置了ID的值也会导致此错误)

 

查阅之后,原来这样违背了hibernate的原理。只能在数据库中再设置为一个自动增加的主键,不涉及到业务层!

 

附上hibernate主键设置的一篇文章(下面来自CSDN博客:http://blog.csdn.net/xiaomo2008/archive/2008/01/07/2029344.aspx

 

hibernate提供了产生自动增长类型主键的多种策略,这里以increment为例说明具体用法: 
1、在数据库中建立表,主键名称为ID,类型为varchar2(字符串型) 
2、在**.hbm.xml(hibernate映射文件)中配置如下 
<class name="com.jat.bisarea.ho.Test" table="BA_VVTEST"> 
<id name="id" type="int" column="ID"> 
//该句指定使用hibernate自带的increment策略生成主键 
<generator class="increment"/> 
</id> 
<property name="uname" type="java.lang.String" column="UNAME"/> 
</class> 
3、在java文件中对表增加记录时,只需添加除ID外的其他字段,然后save即可,相关java代码如下: 
Session s = HibernateUtil.currentSession(); 
Transaction tx = s.beginTransaction(); 
Test test = new Test(); 
String uname = httpServletRequest.getParameter("uname"); 
test.setUname(uname); 
//只需对uname进行set,id由hibernate生成 
s.save(test); 
tx.commit(); 
4、使用其它策略的方法基本一致,例如hilo、seqhilo等

Generator 为每个 POJO 的实例提供唯一标识。一般情况,我们使用“native”。class 表示采用由生成器接口net.sf.hibernate.id.IdentifierGenerator 实现的某个实例,其中包括: 
“assigned” 
主键由外部程序负责生成,在 save() 之前指定一个。 
“hilo” 
通过hi/lo 算法实现的主键生成机制,需要额外的数据库表或字段提供高位值来源。 
“seqhilo” 
与hilo 类似,通过hi/lo 算法实现的主键生成机制,需要数据库中的 Sequence,适用于支持 Sequence 的数据库,如Oracle。 
“increment” 
主键按数值顺序递增。此方式的实现机制为在当前应用实例中维持一个变量,以保存着当前的最大值,之后每次需要生成主键的时候将此值加1作为主键。这种方式可能产生的问题是:不能在集群下使用。 
“identity” 
采用数据库提供的主键生成机制。如DB2、SQL Server、MySQL 中的主键生成机制。 
“sequence” 
采用数据库提供的 sequence 机制生成主键。如 Oralce 中的Sequence。 
“native” 
由 Hibernate 根据使用的数据库自行判断采用 identity、hilo、sequence 其中一种作为主键生成方式。 
“uuid.hex” 
由 Hibernate 基于128 位 UUID 算法生成16 进制数值(编码后以长度32 的字符串表示)作为主键。 
“uuid.string” 
与uuid.hex 类似,只是生成的主键未进行编码(长度16),不能应用在 PostgreSQL 数据库中。 
“foreign” 
使用另外一个相关联的对象的标识符作为主键。
 
 
 
 
1. native 
我最常用的。可以保证多个数据库之间的可移植性。但是有可能有时候会有问题:因为不能控制id值,在数据倒表的时候可能无法满足业务需要。
2. sequence
这种地方可以解决上面用native时候的问题,但是需要堆数据库做一些其他配置。
3. uuid
理论上可以保证多个数据库生成的ID在一个系统里唯一,有时候挺有用。但是效率稍微低点(其实都无所谓)。
4. increment
最好不要用。如果有其他程序访问、修改数据库,那就恐怖了。
5. assigned
没怎么用过。一般不会用手工方式赋值主键,除非有特殊的需求。
6.  foreign
在one-to-one的时候可能会用到。
7. 在使用数据库自动生成主键的时候,SQL语句会有所不同:有些数据库不许你填主键,有些要求你该字段必须为null,有些会完全忽略你写的主键的值。