2016-08-17 88 views
2

我有其主键被定义为会员实体类:如何自动正确生成主键ID使用Hibernate插入记录

@Id 
    @GeneratedValue 
    private Long id; 

我预先加载两个记录与Hibernate的数据库,当我启动应用程序:

insert into Member (id, name, email, phone_number) values (0, 'John Smith', '[email protected]', '2125551212') 
insert into Member (id, name, email, phone_number) values (1, 'Mary Smith', '[email protected]', '2025551212') 

现在MySQL数据库有两个记录:

select * from Member; 
+----+---------------------------+------------+--------------+ 
| id | email      | name  | phone_number | 
+----+---------------------------+------------+--------------+ 
| 0 | [email protected] | John Smith | 2125551212 | 
| 1 | [email protected] | Mary Smith | 2025551212 | 

+ ---- + ------ --------------------- + ------------ + -------------- +

现在,在我的会员注册页面,当我提交申请注册一个新成员,我收到此错误信息:

Caused by: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry '1' for key 'PRIMARY' 

我想,这是因为自动生成的密钥始终开头“ 1',但在数据库中,它已经有两个记录,所以主键'1'将会重复。

我的问题是,如何正确创建主键,给定表中的多个现有记录?如果我不使用

@GeneratedValue 

注释,那么我总是必须在插入之前找出数据库表中的下一个关键点。

有没有最好的方法来处理这种情况,这似乎很常见?

编辑: 至于建议,我用了Stragey:

@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
private Long id; 

什么奇怪的是,如果在表如下两个现有的记录:

select * from English; 
+----+------------+---------+--------+ 
| id | sentence | source | status | 
+----+------------+---------+--------+ 
| 1 | i love you | unknown |  0 | 
| 2 | i like you | unknown |  0 | 
+----+------------+---------+--------+ 

我注册后新的记录到表中,新ID以4开头,不是3,如下所示。

select * from English; 
+----+----------------+---------+--------+ 
| id | sentence  | source | status | 
+----+----------------+---------+--------+ 
| 1 | i love you  | unknown |  0 | 
| 2 | i like you  | unknown |  0 | 
| 4 | I have a book. | Unknown |  0 | 
+----+----------------+---------+--------+ 
3 rows in set (0.00 sec) 

什么可能导致这种情况?

+0

您需要提供表格模式和您用于保存的代码。一般情况下,你只是*不做任何事情*并在保存之前将ID保留为空;这是将它作为包装类型的一点。 – chrylis

+0

不要在插入语句中输入ID – Jens

回答

3

您应该使用IDENTITY生成器。 IDENTITY生成器允许按需自动递增整数和bigint列。增量过程非常有效,因为它使用数据库内部轻量级锁定机制,而不是更重量级的事务性过程锁定机制。

@Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long id; 

并且不要在insert语句中使用id,因为它是自动生成的。
注意SEQUENCE将不会为你工作的序列不与MySQL

+0

我会尝试。谢谢。 – user697911

+0

“按需自动递增”意味着如果表中已经有两条记录“1”和“2”,则会生成一个新的主键“3”而不是1个? – user697911

0
@Id 
@GeneratedValue(strategy=GenerationType.AUTO) 
private Long id; 

当你坚持时,你会离开null (0)

在某些情况下,AUTO战略决心序列,而不是到IDENTITYTABLE,所以你可能需要手动将其设置为IDENTITYTABLE(取决于基础数据库)。

看起来SEQUENCE +指定序列名称适合你。

0

工作对于MySQL,你就可以使用任何下面提到的策略成功地坚持:

@GeneratedValue(strategy=GenerationType.AUTO) 

=>指定主键

@GeneratedValue(strategy=GenerationType.IDENTITY) 

AUTO_INCREMENT属性=>指定主键

AUTO_INCREMENT属性在进一步的高级用法,你可以利用TABLE战略GenerationType.TABLE,在那里你可以指定一个单独的表的主键,你可以指定该表作为@TableGenerator

Hibernate也有一个生成策略:native。它根据底层数据库的功能适当选择生成策略。

0
<id name="id" column="id" type="integer"> 
    <generator class="increment"></generator> 
</id> 

如果您正在使用映射类,则只需使用上述代码自动生成主键。

0

(PostgreSQL系统)。在您填充数据库在末尾添加此脚本:

13 ALTER SEQUENCE RESTART;

看看分贝找到序列名称,例如:

ALTER SEQUENCE role_role_id_seq 13重启;

,你应该能够在模型上anotation来命名生成的序列名称,以及...

希望它能帮助!

相关问题