直截了当,问题是将对象运算符保存到 MySQL 数据库中。在保存之前,我尝试从该表中进行选择并且它有效,与数据库的连接也是如此。
这是我的运算符对象:
@Entity
public class Operator{
@Id
@GeneratedValue
private Long id;
private String username;
private String password;
private Integer active;
//Getters and setters...
}
为了节省,我使用 JPA EntityManager
的 persist
方法。
这是一些日志:
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 not respecting MySQL auto_increment primary key field 但没有任何效果
如果需要任何其他配置文件,我会提供。
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`)
)
要使用 MySQL AUTO_INCREMENT
列,您应该使用 IDENTITY
策略:
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
将 AUTO
与 MySQL 一起使用时,您会得到以下结果:
@Id @GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
这实际上相当于
@Id @GeneratedValue
private Long id;
换句话说,您的映射应该可以工作。但是 Hibernate 应该省略 SQL 插入语句中的 id
列,而事实并非如此。一定有某种不匹配的地方。
您是否在 Hibernate 配置中指定了 MySQL 方言(可能是 MySQL5InnoDBDialect
或 MySQL5Dialect
,具体取决于您使用的引擎)?
另外,谁创建了这张桌子?你能显示相应的DDL吗?
跟进:我无法重现您的问题。使用您的实体和 DDL 的代码,Hibernate 使用 MySQL 生成以下(预期的)SQL:
insert
into
Operator
(active, password, username)
values
(?, ?, ?)
请注意,如预期的那样,上述语句中没有 id
列。
总而言之,您的代码、表格定义和方言是正确且连贯的,它应该可以工作。如果它不适合您,则可能某些内容不同步(进行干净的构建,仔细检查构建目录等)或其他错误(检查日志是否有任何可疑内容)。
关于方言,MySQL5Dialect
和MySQL5InnoDBDialect
之间的唯一区别在于后者在生成DDL时将ENGINE=InnoDB
添加到表对象中。使用其中一种不会更改生成的 SQL。
使用 MySQL,只有这种方法对我有用:
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
帕斯卡在他的回答中所说的其他两种方法对我不起作用。
JPA
与 spring-boot
和 MySQL
一起使用。
@GeneratedValue(strategy=GenerationType.AUTO)
将产生一个额外的表 create table hibernate_sequence (next_val bigint) engine=InnoDB
来产生下一个 id。
对于正在使用 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
另外,为了给出上下文,这是我们正在使用的:
Java 7 Glassfish 3.1 PostgreSQL 9.1 PrimeFaces 3.2/JSF 2.1
另外,为了懒惰,我在 Netbeans 中使用向导构建了这个,用于从 DB 生成实体、从实体生成控制器和从实体生成 JSF,并且向导(显然)不知道如何处理基于序列的 ID 列,所以您必须手动添加这些注释。
如果您在 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")
请确保 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))
那需要
create table VMS_AUDIT_RECORDS (id **bigint** not null auto_increment primary key (id))
如果您使用的是 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/
我尝试了每件事,但仍然无法做到这一点,我正在使用mysql,jpa和hibernate,我通过在构造函数中分配id 0的值来解决我的问题以下是我的id声明代码
@Id
@Column(name="id",updatable=false,nullable=false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long 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...
}
与帕斯卡回答的相同,只是如果您出于某种原因需要使用 .AUTO ,您只需要添加您的应用程序属性:
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.hibernate.ddl-auto = update
你能检查你是否连接到正确的数据库。因为我遇到了同样的问题,但最后我发现我连接到不同的数据库。
identity 支持 DB2、MySQL、MS SQL Server、Sybase 和 HypersonicSQL 中的标识列。返回的标识符是 long、short 或 int 类型。
更多信息:http://docs.jboss.org/hibernate/orm/3.5/reference/en/html/mapping.html#mapping-declaration-id
@GeneratedValue(strategy=GenerationType.AUTO)
和@GeneratedValue
时不会得到@GeneratedValue(strategy=GenerationType.IDENTITY)
。所以要小心,尽量冗长。