Java 如何使用 JPA 注释来注释 MYSQL 自动增量字段

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4102449/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 11:39:04  来源:igfitidea点击:

How to annotate MYSQL autoincrement field with JPA annotations

javamysqlormjpaannotations

提问by trivunm

Straight to the point, problem is saving the object Operator into MySQL DB. Prior to save, I try to select from this table and it works, so is connection to db.

直截了当,问题是将对象 Operator 保存到 MySQL DB 中。在保存之前,我尝试从此表中进行选择并且它有效,与 db 的连接也是如此。

Here is my Operator object:

这是我的 Operator 对象:

@Entity
public class Operator{

   @Id
   @GeneratedValue
   private Long id;

   private String username;

   private String password;


   private Integer active;

   //Getters and setters...
}

To save I use JPA EntityManager's persistmethod.

为了保存我使用 JPAEntityManagerpersist方法。

Here is some log:

这是一些日志:

Hibernate: insert into Operator (active, password, username, id) values (?, ?, ?, ?)
com.mysql.jdbc.JDBC4PreparedStatement@15724a0: insert into Operator (active,password, username, id) values (0, 'pass', 'user', ** NOT SPECIFIED **)

The way I see it, problem is configuration with auto increment but I can't figure out where.

在我看来,问题是自动增量配置,但我不知道在哪里。

Tried some tricks I've seen here: Hibernate not respecting MySQL auto_increment primary key fieldBut nothing of that worked

尝试了一些我在这里看到的技巧: Hibernate notrespecting MySQL auto_increment primary key field但是没有任何效果

If any other configuration files needed I will provide them.

如果需要任何其他配置文件,我会提供它们。

DDL:

DDL:

CREATE TABLE `operator` ( 
`id` INT(10) NOT NULL AUTO_INCREMENT,
`first_name` VARCHAR(40) NOT NULL,
`last_name` VARCHAR(40) NOT NULL,
`username` VARCHAR(50) NOT NULL,
`password` VARCHAR(50) NOT NULL,
`active` INT(1) NOT NULL,
PRIMARY KEY (`id`)
)

回答by Pascal Thivent

To use a MySQL AUTO_INCREMENTcolumn, you are supposed to use an IDENTITYstrategy:

要使用 MySQLAUTO_INCREMENT列,您应该使用一种IDENTITY策略:

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

Which is what you'd get when using AUTOwith MySQL:

AUTO与 MySQL 一起使用时,您会得到什么:

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

Which is actually equivalent to

这实际上相当于

@Id @GeneratedValue
private Long id;

In other words, your mapping should work. But Hibernate should omit the idcolumn in the SQL insert statement, and it is not. There must be a kind of mismatch somewhere.

换句话说,您的映射应该有效。但是 Hibernate 应该省略idSQL 插入语句中的列,而事实并非如此。某处一定有某种不匹配。

Did you specify a MySQL dialect in your Hibernate configuration (probably MySQL5InnoDBDialector MySQL5Dialectdepending on the engine you're using)?

您是否在 Hibernate 配置中指定了 MySQL 方言(可能MySQL5InnoDBDialectMySQL5Dialect取决于您使用的引擎)?

Also, who created the table? Can you show the corresponding DDL?

另外,谁创建了表?你能显示相应的DDL吗?

Follow-up:I can't reproduce your problem. Using the code of yourentity and yourDDL, Hibernate generates the following (expected) SQL with MySQL:

后续:我无法重现您的问题。使用的代码,你的实体,您的DDL,Hibernate会与MySQL以下(预期)SQL:

insert 
into
    Operator
    (active, password, username) 
values
    (?, ?, ?)

Note that the idcolumn is absent from the above statement, as expected.

请注意id,正如预期的那样,上述语句中没有该列。

To sum up, your code, the table definition and the dialect are correct and coherent, it should work. If it doesn't for you, maybe something is out of sync (do a clean build, double check the build directory, etc) or something else is just wrong (check the logs for anything suspicious).

综上所述,您的代码、表定义和方言是正确且连贯的,应该可以工作。如果它不适合您,则可能是某些内容不同步(进行干净的构建,仔细检查构建目录等)或其他错误(检查日志中是否有任何可疑内容)。

Regarding the dialect, the onlydifference between MySQL5Dialector MySQL5InnoDBDialectis that the later adds ENGINE=InnoDBto the table objects when generating the DDL. Using one or the other doesn't change the generated SQL.

关于方言,or 之间的唯一区别是后者在生成 DDL 时添加到表对象中。使用其中之一不会更改生成的 SQL。MySQL5DialectMySQL5InnoDBDialectENGINE=InnoDB

回答by Max Awesome

For anyone reading this who is using EclipseLink for JPA 2.0, here are the two annotations I had to use to get JPA to persist data, where "MySequenceGenerator" is whatever name you want to give the generator, "myschema" is the name of the schema in your database that contains the sequence object, and "mysequence" is the name of the sequence object in the database.

对于使用 EclipseLink for JPA 2.0 的任何人,这里是我必须使用的两个注释来让 JPA 持久化数据,其中“MySequenceGenerator”是你想给生成器的任何名称,“myschema”是包含序列对象的数据库中的架构,“mysequence”是数据库中序列对象的名称。

@GeneratedValue(strategy= GenerationType.SEQUENCE, generator="MySequenceGenerator")
@SequenceGenerator(allocationSize=1, schema="myschema",  name="MySequenceGenerator", sequenceName = "mysequence")

For those using EclipseLink (and possibly other JPA providers), it is CRITICAL that you set the allocationSize attribute to match the INCREMENT value defined for your sequence in the database. If you don't, you'll get a generic persistence failure, and waste a good deal of time trying to track it down, like I did. Here is the reference page that helped me overcome this challenge:

对于那些使用 EclipseLink(可能还有其他 JPA 提供程序)的人来说,将 allocationSize 属性设置为匹配数据库中为序列定义的 INCREMENT 值是至关重要的。如果你不这样做,你会得到一个通用的持久性失败,并浪费大量时间试图追踪它,就像我所做的那样。这是帮助我克服这一挑战的参考页面:

http://wiki.eclipse.org/EclipseLink/Examples/JPA/PrimaryKey#Using_Sequence_Objects

http://wiki.eclipse.org/EclipseLink/Examples/JPA/PrimaryKey#Using_Sequence_Objects

Also, to give context, here is what we're using:

此外,为了提供上下文,这是我们正在使用的内容:

Java 7 Glassfish 3.1 PostgreSQL 9.1 PrimeFaces 3.2/JSF 2.1

Java 7 Glassfish 3.1 PostgreSQL 9.1 PrimeFaces 3.2/JSF 2.1

Also, for laziness' sake, I built this in Netbeans with the wizards for generating Entities from DB, Controllers from Entities, and JSF from Entities, and the wizards (obviously) do not know how to deal with sequence-based ID columns, so you'll have to manually add these annotations.

此外,为了懒惰,我在 Netbeans 中构建了它,其中包含从 DB 生成实体、从实体生成控制器和从实体生成 JSF 的向导,并且这些向导(显然)不知道如何处理基于序列的 ID 列,所以您必须手动添加这些注释。

回答by Jelle

Using MySQL, only this approach was working for me:

使用 MySQL,只有这种方法对我有用:

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

The other 2 approaches stated by Pascal in his answer were not working for me.

Pascal 在他的回答中提到的其他 2 种方法对我不起作用。

回答by ABHAY JOHRI

Please make sure that id datatype is Long instead of String, if that will be string then @GeneratedValue annotation will not work and the sql generating for

请确保 id 数据类型是 Long 而不是 String,如果它是字符串,那么 @GeneratedValue 注释将不起作用并且生成的 sql

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

create table VMS_AUDIT_RECORDS (id **varchar(255)** not null auto_increment primary key (id))

that needs to be

那必须是

create table VMS_AUDIT_RECORDS (id **bigint** not null auto_increment primary key (id))

回答by M. Waseem Ullah Khan

I tried every thing, but still I was unable to do that, I am using mysql, jpa with hibernate, I resolved my issue by assigning value of id 0 in constructor Following is my id declaration code

我尝试了所有事情,但仍然无法做到这一点,我正在使用 mysql、jpa 和 hibernate,我通过在构造函数中分配 id 0 的值解决了我的问题以下是我的 id 声明代码

@Id
@Column(name="id",updatable=false,nullable=false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

回答by Mohan Reddy

can you check whether you connected to the correct database. as i was faced same issue, but finally i found that i connected to different database.

你能检查一下你是否连接到了正确的数据库。因为我遇到了同样的问题,但最后我发现我连接到了不同的数据库。

identitysupports identity columns in DB2, MySQL, MS SQL Server, Sybase and HypersonicSQL. The returned identifier is of type long, short or int.

identity支持 DB2、MySQL、MS SQL Server、Sybase 和 HypersonicSQL 中的标识列。返回的标识符是 long、short 或 int 类型。

More Info : http://docs.jboss.org/hibernate/orm/3.5/reference/en/html/mapping.html#mapping-declaration-id

更多信息:http: //docs.jboss.org/hibernate/orm/3.5/reference/en/html/mapping.html#mapping-declaration-id

回答by Anjali Pavithra

As you have define the id in int type at the database creation, you have to use the same data type in the model class too. And as you have defined the id to auto increment in the database, you have to mention it in the model class by passing value 'GenerationType.AUTO' into the attribute 'strategy' within the annotation @GeneratedValue. Then the code becomes as below.

由于您在创建数据库时已将 id 定义为 int 类型,因此您也必须在模型类中使用相同的数据类型。并且由于您已将 id 定义为在数据库中自动递增,因此您必须通过将值“GenerationType.AUTO”传递到注释@GeneratedValue 中的属性“strategy”来在模型类中提及它。然后代码变成如下。

@Entity
public class Operator{

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

  private String username;

  private String password;

  private Integer active;

  //Getters and setters...
}

回答by dmarquina

If you are using Mysql with Hibernate v3 it's ok to use GenerationType.AUTObecause internally it will use GenerationType.IDENTITY, which is the most optimal in for MySQL.

如果您将 Mysql 与 Hibernate v3 一起使用GenerationType.AUTO,则可以使用GenerationType.IDENTITY,因为在内部它将使用,这是 MySQL 中最优化的。

However in Hibernate v5, It has changed. GenerationType.AUTOwill use GenerationType.TABLEwhich generates to much queries for the insertion.

但是在 Hibernate v5 中,它发生了变化。GenerationType.AUTO将使用GenerationType.TABLEwhich 为插入生成大量查询。

You can avoid that using GenerationType.IDENTITY(if MySQL is the only database you are using) or with these notations (if you have multiple databases):

您可以避免使用GenerationType.IDENTITY(如果 MySQL 是您使用的唯一数据库)或使用这些符号(如果您有多个数据库):

@GeneratedValue(strategy = GenerationType.AUTO, generator = "native")
@GenericGenerator(name = "native", strategy = "native")

回答by Jorge

same as pascal answered, just if you need to use .AUTO for some reason you just need to add in your application properties:

与 pascal 回答相同,如果您出于某种原因需要使用 .AUTO ,则只需添加应用程序属性:

spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.hibernate.ddl-auto = update