hibernate的主键生成策略常用的有三种,uuid,native,和assigned三种,三种不同的配置方式对数据库发送sql语句的时机也有略微的不同,下面进行以下总结:
数据库我们采用的是mysql,隔离级别为读已提交
我们关注的主要是session中的existsInDatabase属性
1:uuid
save: existsInDatabase=false
flush: existsInDatabase=true
2:native
save: existsInDatabase=true
3:assigned
save: existsInDatabase=false
flush: existsInDatabase=true
结论:uuid和assigned由于都不是数据库生成的主键,所以会在执行flush的时候执行刷出镜像数据,执行sql语句
而native会在执行save的时候执行sql语句原因是生成主键的时候需要数据库的支持,那么会产生的现象就是,策略
不是native时我们执行save后再evict,将会出现异常在session的insertions集合中取出对象进行insert操作后
需要更新entityEntries属性中的existsInDatabase为true,而我们采用evict已经将对象从session的entityEntries
中逐出了,所以找不到相关数据,无法更新,抛出异常。并且会发现,flush的时候sql语句的执行顺序是insert
update,delete 并不是按照我们代码的顺序
所以,当主键生成策略为非native时,为了避免不必要的麻烦记得及时的flush