简体   繁体   English

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

[英]How to annotate MYSQL autoincrement field with JPA annotations

Straight to the point, problem is saving the object Operator into MySQL DB.直截了当,问题是将对象 Operator 保存到 MySQL DB 中。 Prior to save, I try to select from this table and it works, so is connection to 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 persist method.为了保存,我使用 JPA EntityManagerpersist方法。

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 field But 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`)
)

To use a MySQL AUTO_INCREMENT column, you are supposed to use an IDENTITY strategy:要使用 MySQL AUTO_INCREMENT列,您应该使用IDENTITY策略:

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

Which is what you'd get when using AUTO with MySQL:这是在 MySQL 中使用AUTO时会得到的结果:

@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 id column in the SQL insert statement, and it is not.但是 Hibernate 应该在 SQL 插入语句中省略id列,而事实并非如此。 There must be a kind of mismatch somewhere.某处一定有某种不匹配。

Did you specify a MySQL dialect in your Hibernate configuration (probably MySQL5InnoDBDialect or MySQL5Dialect depending 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 your entity and your DDL, Hibernate generates the following (expected) SQL with MySQL:使用你的实体和您的DDL的代码,Hibernate的生成与MySQL以下(预期)SQL:

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

Note that the id column 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 only difference between MySQL5Dialect or MySQL5InnoDBDialect is that the later adds ENGINE=InnoDB to the table objects when generating the DDL.关于方言, MySQL5DialectMySQL5InnoDBDialect唯一区别是后者在生成 DDL 时将ENGINE=InnoDB添加到表对象中。 Using one or the other doesn't change the generated SQL.使用其中之一不会更改生成的 SQL。

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 种方法对我不起作用。

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.对于那些使用 EclipseLink(可能还有其他 JPA 提供程序)的人来说,将 allocationSize 属性设置为匹配数据库中为序列定义的 INCREMENT 值是至关重要的。 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:这是帮助我克服这一挑战的参考页面:

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 列,所以您必须手动添加这些注释。

If you are using Mysql with Hibernate v3 it's ok to use GenerationType.AUTO because 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.但是在 Hibernate v5 中,它发生了变化。 GenerationType.AUTO will use GenerationType.TABLE which generates to much queries for the insertion. GenerationType.AUTO将使用GenerationType.TABLE ,它为插入生成大量查询。

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")

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))

If you are using MariaDB this will work如果您使用的是 MariaDB,这将起作用

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

For more, you can check https://thorben-janssen.com/hibernate-tips-use-auto-incremented-column-primary-key/有关更多信息,您可以查看https://thorben-janssen.com/hibernate-tips-use-auto-incremented-column-primary-key/

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;

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

@Entity
public class Operator{

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

  private String username;

  private String password;

  private Integer active;

  //Getters and setters...
}

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

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.因为我遇到了同样的问题,但最后我发现我连接到了不同的数据库。

identity supports identity columns in DB2, MySQL, MS SQL Server, Sybase and HypersonicSQL. identity支持 DB2、MySQL、MS SQL Server、Sybase 和 HypersonicSQL 中的标识列。 The returned identifier is of type long, short or int.返回的标识符是 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM