如何用JPA批注注释MYSQL自动增量字段
直接点,问题是保存对象运营商到MySQL数据库。 在保存之前,我尝试从这个表中select,它的工作原理,连接到数据库也是如此。
这是我的操作对象:
@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 **)
我看到它的方式,问题是自动增量configuration,但我不知道在哪里。
试过一些我在这里看到的技巧: hibernate不尊重MySQL的auto_increment主键字段但没有任何工作
如果需要其他configuration文件,我将提供它们。
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
列,而不是。 在某个地方肯定会有一种错配。
你有没有在你的Hibernateconfiguration中指定一个MySQL方言(可能是MySQL5InnoDBDialect
或MySQL5Dialect
取决于你使用的引擎)?
另外,谁创build了这个表? 你能显示相应的DDL吗?
跟进:我不能重现你的问题。 使用你的实体和你的 DDL的代码,Hibernate用MySQL生成以下(预期的)SQL:
insert into Operator (active, password, username) values (?, ?, ?)
请注意,上面的语句中没有id
列,正如所料。
总之,你的代码,表格定义和方言是正确和连贯的,它应该工作。 如果它不适合你,也许有些东西是不同步的(做一个干净的构build,仔细检查构build目录等)或者其他东西是错误的(检查日志中是否有可疑的东西)。
关于方言, MySQL5Dialect
或MySQL5InnoDBDialect
的唯一区别在于,在生成DDL时,后者将ENGINE=InnoDB
添加到表对象中。 使用其中一个不会更改生成的SQL。
使用MySQL,只有这种方法适用于我:
@Id @GeneratedValue(strategy=GenerationType.IDENTITY) private Long 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列,您必须手动添加这些注释。
请确保id数据types是Long而不是String,如果那是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))