Hibernate主键生成策略问题在工作中遇到多次,但用过去后就忘掉了,没有整理总结,每次用时都重新查资料,但网上的一些资料好像有问题,现趁有时间简单总结一下。测试版本为Hibernate 3.6.10,测试数据库为MySql。
1.JPA提供的四种标准用法为TABLE,SEQUENCE,IDENTITY,AUTO:
TABLE:使用一个特定的数据库表格来保存主键,没有用过
SEQUENCE:根据底层数据库的序列来生成主键,如Oracle
IDENTITY:自增主键由底层数据库自动生成
AUTO:为默认策略,根据数据库自动选择合适策略,类似Hibernate的native策略
如果不设GeneratedValue,即不使用策略,主键由程序控制,需手动设置ID
具体测试过程如下:
@Entity
public class User {
private int id;
private String name;
private int age;
@Id
public int getId() {
return id;
}
//......
}
执行save操作,打印sql为Hibernate: insert into User (age, name, id) values (?, ?, ?),可见sql中插入了id字段,也就是说id是手动输入的。
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public int getId() {
return id;
}
当
GeneratedValue设为IDENTITY时,执行save操作,打印sql为Hibernate: insert into User (age, name) values (?, ?),没有插入id字段值,即使在程序中设置了id值,数据库中id字段自增,可见是依赖底层数据库自增字段,经测试如果数据库中id字段不自增则执行报错。
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
// @GeneratedValue
public int getId() {
return id;
}
当GeneratedValue设为AUTO或不设时,执行save操作,打印sql为Hibernate: insert into User (age, name) values (?, ?),执行结果和IDENTITY时一样,此处应该是同hibernate 的 native策略相同,Oracle时使用sequence策略,但只验证了MySql数据库Oracle没有验证。
2.Hibernate在JPA的基础上进行了扩展,只用过native和uuid:
native:需底层数据库的支持,对于 MySQL,SQL Server 采用 identity 的生成策略,对于 Oracle,则采用 sequence 策略。同JPA的AUTO策略。
@Id
@GeneratedValue(generator="myGenerator")
@GenericGenerator(name="myGenerator", strategy="native")
uuid:根据网卡MAC地址,IP,主机名,进程ID等信息生成唯一代码,保证数据独立性
@Id
@GeneratedValue(generator="myGenerator")
@GenericGenerator(name="myGenerator", strategy="uuid")