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

直奔主题,问题是将对象 Operator 保存到 MySQLDB 中。 在保存之前,我尝试从这个表中进行选择,它能够工作,连接到 db 也能够工作。

以下是 Operator 对象:

@Entity
public class Operator{


@Id
@GeneratedValue
private Long id;


private String username;


private String password;




private Integer active;


//Getters and setters...
}

为了保存,我使用 JPAEntityManagerpersist方法。

这是一些日志:

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

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

尝试了一些我在这里看到的技巧: Hibernate 不尊重 MySQL auto _ growth 主键字段 ,但是这些都不起作用

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

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`)
)
285850 次浏览

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

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

这就是在 MySQL 中使用 AUTO时会得到的结果:

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

实际上相当于

@Id @GeneratedValue
private Long id;

换句话说,映射应该可以工作。但是 Hibernate 应该在 SQL 插入语句中省略 id列,而实际情况并非如此。肯定有什么地方不匹配。

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

还有,谁创建了这个表? 你能显示相应的 DDL 吗?

跟进: 我无法复制你的问题。使用 你的实体代码和 你的 DDL,Hibernate 使用 MySQL 生成以下(预期的) SQL:

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

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

总之,您的代码、表定义和方言是正确和连贯的,它应该工作。如果它不适合你,也许有些东西不同步(做一个干净的构建,再次检查构建目录,等等)或者其他东西只是错误的(检查任何可疑的日志)。

关于方言,MySQL5DialectMySQL5InnoDBDialect之间的 只有区别在于后者在生成 DDL 时将 ENGINE=InnoDB添加到表对象中。使用其中一种并不会改变生成的 SQL。

对于正在使用 EclipseLink For JPA 2.0的读者来说,这里有两个注释,我必须使用它们来让 JPA 保存数据,其中“ MySequenceGenerator”是你想给生成器起的任何名字,“ myschema”是数据库中包含序列对象的模式的名称,“ mySequence”是数据库中序列对象的名称。

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

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

Http://wiki.eclipse.org/eclipselink/examples/jpa/primarykey#using_sequence_objects

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

爪哇7 玻璃鱼3.1 PostgreSQL 9.1 PrimeFaces 3.2/JSF 2.1

另外,为了懒惰起见,我在 Netbeans 使用了从 DB 生成实体的向导、从实体生成控制器的向导和从实体生成 JSF 的向导,而这些向导(显然)不知道如何处理基于序列的 ID 列,所以你必须手动添加这些注释。

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

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

帕斯卡在他的回答中提到的另外两种方法对我不起作用。

请确保 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))

这是必须的

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

我尝试了所有的方法,但仍然不能做到这一点,我使用 mysql,jpa 和 hibernate,我通过在构造函数中赋值 id 0来解决我的问题 下面是我的 id 声明代码

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

您能否检查是否连接到正确的数据库。因为我面临同样的问题,但最终我发现我连接到不同的数据库。

支持 DB2、 MySQL、 MSSQLServer、 Sybase 和 HypersicSQL 中的标识列。返回的标识符的类型为 long、 short 或 int。

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

由于在创建数据库时已经在 int 类型中定义了 id,因此也必须在模型类中使用相同的数据类型。在数据库中定义了自动增量的 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...
}

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

但是在 Hibernate v5中,它已经改变了。 GenerationType.AUTO将使用 GenerationType.TABLE,这将生成许多用于插入的查询。

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

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

就像帕斯卡回答的一样,只是如果你需要使用。出于某种原因,您只需要添加应用程序属性:

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

如果你正在使用 MariaDB 这将工作

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

如果想了解更多,可以查看 https://thorben-janssen.com/hibernate-tips-use-auto-incremented-column-primary-key/