2010-11-04 157 views
75

直截了當,問題是將對象操作符保存到MySQL DB中。 保存之前,我嘗試從這張表中選擇它,它的工作原理,連接到數據庫也是如此。如何使用JPA批註註釋MYSQL自動增量字段

這裏是我的操作對象:

@Entity 
public class Operator{ 

    @Id 
    @GeneratedValue 
    private Long id; 

    private String username; 

    private String password; 


    private Integer active; 

    //Getters and setters... 
} 

爲了節省我使用JPA EntityManagerpersist方法。

下面是一些日誌:

Hibernate: insert into Operator (active, password, username, id) values (?, ?, ?, ?) 
[email protected]: 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`) 
) 
+0

你使用的是什麼版本的Hibernate? – 2010-11-06 21:19:11

+0

休眠3.2.4 – trivunm 2010-11-06 21:38:48

回答

110

要使用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方言(可能爲MySQL5InnoDBDialectMySQL5Dialect,具體取決於您使用的引擎)?

另外,誰創建了表?你能顯示相應的DDL嗎?

後續問題:我無法重現您的問題。使用實體和 DDL的代碼,Hibernate的生成與MySQL以下(預期)SQL:

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

注意,id列是從上面的語句不存在,符合市場預期。總之,你的代碼,表格定義和方言是正確和連貫的,它應該工作。如果它不適合你,也許有些東西是不同步的(做一個乾淨的構建,仔細檢查構建目錄等)或其他東西是錯誤的(檢查日誌中是否有任何可疑內容)。

關於方言的MySQL5DialectMySQL5InnoDBDialect之間僅區別是,後來生成DDL時添加ENGINE=InnoDB表對象。使用其中一個不會更改生成的SQL。

+0

帕斯卡爾,你是對的,但在我的配置文件中的東西是不正確的。任何其他建議也許,現在我已經把新的信息和配置文件? – trivunm 2010-11-16 22:17:48

+9

@Pascal - 我發現我需要@GeneratedValue(strategy = GenerationType.IDENTITY)來使AUTO_INCREMENT在使用JPA 2/Hibernate 4.0.0.CR2/JBoss AS 7時正常工作。http://bit.ly/ tdNyOJ – 2011-10-26 18:35:24

+4

請注意,對於MySQL MySQL,這是正確的。使用** PostgreSQL **,當您編寫'@GeneratedValue(strategy = GenerationType.AUTO)'和'@ GeneratedValue'時,您不會獲得'@GeneratedValue(strategy = GenerationType.IDENTITY)'。所以要小心並儘量做到冗長。 – sajjadG 2013-11-08 11:00:43

11

對於任何讀者使用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屬性匹配數據庫中的序列定義的增量值。如果你不這樣做,你會得到一個通用的持久性失敗,並且浪費大量的時間試圖追蹤它,就像我一樣。下面是幫助我克服這個挑戰的參考頁:

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生成嚮導,嚮導(顯然)不知道如何處理sequen基於ce的ID列,所以您必須手動添加這些註釋。

19

使用MySQL,只有這個辦法是爲我工作:

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

並沒有爲我工作帕斯卡在他的回答中規定的其他2點的方法。

+0

是的,我在我的問題/答案中提到了這一點。 HTTP://計算器。COM /問題/ 39675714 /架構驗證缺失表,休眠序列/ 39675802#39675802 – 2016-09-24 11:29:58

3

請確保該ID的數據類型是龍,而不是字符串,如果 將字符串,然後@GeneratedValue註釋,將無法正常工作和

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

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

的 SQL生成需要成爲

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