直截了当,问题是将对象操作员保存到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...
}
要保存我使用JPA EntityManager
的{{1}}方法。
这是一些日志:
persist
我看到它的方式,问题是配置有自动增量,但我无法弄清楚在哪里。
尝试过我在这里看到的一些技巧: Hibernate not respecting MySQL auto_increment primary key field但是没有任何效果
如果需要任何其他配置文件,我将提供它们。
DDL:
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 **)
答案 0 :(得分:126)
要使用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 insert语句中的id
列,而不是。某处肯定会有一种不匹配。
您是否在Hibernate配置中指定了MySQL方言(可能MySQL5InnoDBDialect
或MySQL5Dialect
,具体取决于您使用的引擎)?
另外,谁创造了这张桌子?你能展示相应的DDL吗?
跟进:我无法重现您的问题。使用您的实体的代码和您的 DDL,Hibernate使用MySQL生成以下(预期)SQL:
insert
into
Operator
(active, password, username)
values
(?, ?, ?)
请注意,正如预期的那样,上述语句中不存在id
列。
总而言之,您的代码,表格定义和方言是正确和连贯的,它应该有效。如果它不适合你,也许某些东西不同步(做一个干净的构建,仔细检查构建目录等)或其他东西是错误的(检查日志中是否有任何可疑的东西)。
关于方言,MySQL5Dialect
或MySQL5InnoDBDialect
之间仅的区别在于后者在生成DDL时将ENGINE=InnoDB
添加到表对象。使用其中一个不会更改生成的SQL。
答案 1 :(得分:30)
使用MySQL,只有这种方法对我有用:
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
帕斯卡尔在答案中提出的另外两种方法并不适用于我。
答案 2 :(得分: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")
对于那些使用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列,因此您必须手动添加这些注释。
答案 3 :(得分:5)
请确保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))
答案 4 :(得分:1)
在创建数据库时,您已经在int类型中定义了id,因此您也必须在模型类中使用相同的数据类型。而且,由于您已将ID定义为在数据库中自动递增,因此您必须在模型类中通过将值“ GenerationType.AUTO”传递到@GeneratedValue批注中的属性“ strategy”中来提及它。然后代码如下所示。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined(__APPLE__)
# define COMMON_DIGEST_FOR_OPENSSL
# include <CommonCrypto/CommonDigest.h>
# define SHA1 CC_SHA1
#else
# include <openssl/md5.h>
#endif
char *str2md5(const char *str, int length) {
int n;
MD5_CTX c;
unsigned char digest[16];
char *out = (char*)malloc(33);
MD5_Init(&c);
while (length > 0) {
if (length > 512) {
MD5_Update(&c, str, 512);
} else {
MD5_Update(&c, str, length);
}
length -= 512;
str += 512;
}
MD5_Final(digest, &c);
for (n = 0; n < 16; ++n) {
snprintf(&(out[n*2]), 16*2, "%02x", (unsigned int)digest[n]);
}
return out;
}
int main(int argc, char **argv) {
char *output = str2md5("hello", strlen("hello"));
printf("%s\n", output);
free(output);
return 0;
}
答案 5 :(得分:1)
如果您将Mysql与Hibernate v3结合使用,则可以使用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")
答案 6 :(得分:1)
与pascal回答相同,只是由于某种原因您需要使用.AUTO时,您只需要添加应用程序属性即可:
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.hibernate.ddl-auto = update
答案 7 :(得分:1)
如果您使用的是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/
答案 8 :(得分:0)
我尝试了所有的东西,但我仍然无法做到这一点,我使用mysql,jpa与hibernate,我通过在构造函数中赋值id 0解决了我的问题 以下是我的id声明代码
@Id
@Column(name="id",updatable=false,nullable=false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
答案 9 :(得分:0)
可以检查是否连接到正确的数据库。因为我遇到了同样的问题,但最终我发现我连接到了另一个数据库。
身份 支持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