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

tri*_*unm 98 java mysql orm annotations jpa

直截了当,问题是将对象操作员保存到MySQL DB中.在保存之前,我尝试从此表中进行选择并且它可以正常工作,因此是与db的连接.

这是我的Operator对象:

@Entity
public class Operator{

   @Id
   @GeneratedValue
   private Long id;

   private String username;

   private String password;


   private Integer active;

   //Getters and setters...
}
Run Code Online (Sandbox Code Playgroud)

为了保存我使用JPA EntityManagerpersist方法.

这是一些日志:

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 **)
Run Code Online (Sandbox Code Playgroud)

我看到它的方式,问题是配置自动增量但我无法弄清楚在哪里.

试过我在这里看到的一些技巧: Hibernate不尊重MySQL auto_increment主键字段但是没有任何有用的

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

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`)
)
Run Code Online (Sandbox Code Playgroud)

Pas*_*ent 133

要使用MySQL AUTO_INCREMENT列,您应该使用IDENTITY策略:

@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
Run Code Online (Sandbox Code Playgroud)

使用AUTOMySQL 时会得到以下内容:

@Id @GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
Run Code Online (Sandbox Code Playgroud)

这实际上相当于

@Id @GeneratedValue
private Long id;
Run Code Online (Sandbox Code Playgroud)

换句话说,您的映射应该有效.但是Hibernate应该省略idSQL insert语句中的列,而不是.某处必定存在某种不匹配.

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

还有谁创造了这张桌子?你能展示相应的DDL吗?

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

insert 
into
    Operator
    (active, password, username) 
values
    (?, ?, ?)
Run Code Online (Sandbox Code Playgroud)

请注意id,正如预期的那样,上述语句中不存在该列.

总而言之,您的代码,表格定义和方言是正确和连贯的,它应该有效.如果它不适合你,也许某些东西不同步(做一个干净的构建,仔细检查构建目录等)或其他东西是错误的(检查日志中是否有任何可疑的东西).

关于方言中,唯一的区别MySQL5DialectMySQL5InnoDBDialect在于后来增加了ENGINE=InnoDB生成DDL时表对象.使用其中一个不会更改生成的SQL.

  • @Pascal - 我发现在使用JPA 2/Hibernate 4.0.0.CR2/JBoss AS 7时我需要@GeneratedValue(strategy = GenerationType.IDENTITY)才能使AUTO_INCREMENT正常工作.http://bit.ly/tdNyOJ (9认同)
  • 请注意,**MySQL**也是如此.使用**PostgreSQL**,当你编写`@GeneratedValue(strategy = GenerationType.AUTO)`和`@GeneratedValue`时,你不会得到`@GeneratedValue(strategy = GenerationType.IDENTITY)`.所以要小心,并尝试冗长. (4认同)

Jel*_*lle 32

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

@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
Run Code Online (Sandbox Code Playgroud)

Pascal在他的回答中提出的其他两种方法对我不起作用.


小智 12

对于那些正在阅读这个使用EclipseLink for JPA 2.0的人来说,这里有两个注释我必须用来让JPA保持数据,其中"MySequenceGenerator"是你想给发生器的名字,"myschema"是这个名字.数据库中包含序列对象的模式,"mysequence"是数据库中序列对象的名称.

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

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

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

另外,为了给出上下文,这是我们正在使用的:

Java 7 Glassfish 3.1 PostgreSQL 9.1 PrimeFaces 3.2/JSF 2.1

另外,为了懒惰,我在Netbeans中构建了这个用于从DB生成实体的向导,来自实体的控制器和来自实体的JSF,并且向导(显然)不知道如何处理基于序列的ID列,所以你必须手动添加这些注释.


dma*_*ina 8

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

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

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

@GeneratedValue(strategy = GenerationType.AUTO, generator = "native")
@GenericGenerator(name = "native", strategy = "native")
Run Code Online (Sandbox Code Playgroud)


ABH*_*HRI 5

请确保id数据类型为Long而不是String,如果它将为字符串,则@GeneratedValue批注将不起作用,并且为

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

create table VMS_AUDIT_RECORDS (id **varchar(255)** not null auto_increment primary key (id))
Run Code Online (Sandbox Code Playgroud)

那应该是

create table VMS_AUDIT_RECORDS (id **bigint** not null auto_increment primary key (id))
Run Code Online (Sandbox Code Playgroud)


Ade*_*del 5

如果您使用的是 MariaDB,这将起作用

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

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