java 如何使用 Hibernate 插入记录正确自动生成主键 ID
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/38988757/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to auto generate primary key ID properly with Hibernate inserting records
提问by user697911
I have a Member entity class whose primary key is defined as:
我有一个 Member 实体类,其主键定义为:
@Id
@GeneratedValue
private Long id;
I pre-loaded two records into database with Hibernate when I starts the application:
当我启动应用程序时,我使用 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')
Now the MySql database has two records:
现在MySql数据库有两条记录:
select * from Member;
+----+---------------------------+------------+--------------+
| id | email | name | phone_number |
+----+---------------------------+------------+--------------+
| 0 | [email protected] | John Smith | 2125551212 |
| 1 | [email protected] | Mary Smith | 2025551212 |
+----+---------------------------+------------+--------------+
+----+---------------------------+------------+--- -----------+
Now, in my member registration page, when I submit a request to register a new member, I received this error message:
现在,在我的会员注册页面中,当我提交注册新会员的请求时,收到此错误消息:
Caused by: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry '1' for key 'PRIMARY'
I figured that it because the auto-generated key always starts with '1', but in the database, it already has two records, so the primary key '1' will be duplicate.
我想这是因为自动生成的键总是以'1'开头,但在数据库中,它已经有两条记录,所以主键'1'会重复。
My question is, how to create the primary key properly, given a number of existing records in the table? If I don't use the
我的问题是,鉴于表中存在大量现有记录,如何正确创建主键?如果我不使用
@GeneratedValue
annotation, then I always have to find out what's the next key from the database table before insertion.
注释,那么我总是必须在插入之前从数据库表中找出下一个键是什么。
Is there a best way to handle this situation, which seems very common?
有没有最好的方法来处理这种情况,这似乎很常见?
EDITED: As suggested, I used the Stragey:
编辑:按照建议,我使用了 Stragey:
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
What's strange is that, if there are two existing records in the table as below:
奇怪的是,如果表中有两条记录如下:
select * from English;
+----+------------+---------+--------+
| id | sentence | source | status |
+----+------------+---------+--------+
| 1 | i love you | unknown | 0 |
| 2 | i like you | unknown | 0 |
+----+------------+---------+--------+
after I register a new record into the table, the new ID starts with 4, not 3, as below.
在我将新记录注册到表中后,新 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)
What might cause this?
什么可能导致这种情况?
回答by amit
You should use IDENTITY
generator. The IDENTITY
generator allows an integer and bigint column to be auto-incremented on demand. The increment process is very efficient since it uses a database internal lightweight locking mechanism as opposed to the more heavyweight transactional course-grain locks.
你应该使用IDENTITY
发电机。该IDENTITY
发生器允许一个整数,BIGINT列是自动递增的需求。增量过程非常有效,因为它使用数据库内部轻量级锁定机制,而不是更重量级的事务性粗粒锁。
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
And don't use id in the insert statement as it is being generated automatically.
Note that SEQUENCE will not work for you as SEQUENCE does not work with MySQL
并且不要在插入语句中使用 id,因为它是自动生成的。
请注意, SEQUENCE 对您不起作用,因为 SEQUENCE 不适用于 MySQL
回答by Akash Mishra
For MySQL, you'll be able to successfully persist using any of the below mentioned strategies:
对于 MySQL,您将能够使用下面提到的任何策略成功持久化:
@GeneratedValue(strategy=GenerationType.AUTO)
=> specify auto_increment attribute for primary key
=> 为主键指定 auto_increment 属性
@GeneratedValue(strategy=GenerationType.IDENTITY)
=>specify auto_increment attribute for primary key
=> 为主键指定 auto_increment 属性
On a further advanced usage, you can make use of TABLE
strategy GenerationType.TABLEwhere you can specify the primary key from a separate table and you can specify this table as @TableGenerator
在进一步的高级用法中,您可以使用TABLE
策略GenerationType.TABLE,您可以在其中从单独的表中指定主键,并且可以将此表指定为@TableGenerator
Hibernate also has a generation strategy: native
. It appropriately selects the generation strategy based upon the underlying database's capability.
Hibernate 还有一个生成策略:native
. 它根据底层数据库的能力适当地选择生成策略。
回答by Priyanka Patil
<id name="id" column="id" type="integer">
<generator class="increment"></generator>
</id>
In case if you are using mapping classes then just use above code to generate primary key automatically.
如果您正在使用映射类,那么只需使用上面的代码自动生成主键。
回答by user1568220
(postgresql) In the script where you populate the db add this at the end :
(postgresql) 在填充数据库的脚本中,在最后添加:
ALTER SEQUENCE RESTART WITH 13;
ALTER SEQUENCE RESTART 为 13;
look at the db to find the seq name, example :
查看数据库以查找序列名称,例如:
ALTER SEQUENCE role_role_id_seq RESTART WITH 13;
ALTER SEQUENCE role_role_id_seq RESTART WITH 13;
you should be able to name the generated sequence name as well with the anotation on the model...
您应该能够使用模型上的注释命名生成的序列名称......
hope it helps !
希望能帮助到你 !
回答by Deva
Now in Hibernate 5.2 you just need check @GeneratedValue(strategy = IDENTITY)
at Variable level OR method level.
现在在 Hibernate 5.2 中,您只需要@GeneratedValue(strategy = IDENTITY)
在变量级别或方法级别进行检查。
@Id
@GeneratedValue(strategy = IDENTITY)
private Integer id;
or
或者
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "Id", unique = true, nullable = false)
public Integer getId() {
return this.id;
}
回答by Saurav Wahid
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
and you leave it null (0)
when persisting.
null (0)
当你坚持的时候你就离开了。
In some cases the AUTO
strategy is resolved to SEQUENCE rather than to IDENTITY
or TABLE
, so you might want to manually set it to IDENTITY
or TABLE
(depending on the underlying database).
在某些情况下,AUTO
策略被解析为 SEQUENCE 而不是IDENTITY
或TABLE
,因此您可能需要手动将其设置为IDENTITY
或TABLE
(取决于底层数据库)。
It seems SEQUENCE + specifying the sequence name worked for you.
似乎 SEQUENCE + 指定序列名称对您有用。