簡體   English   中英

如何使用 JPA 注釋來注釋 MYSQL 自動增量字段

[英]How to annotate MYSQL autoincrement field with JPA annotations

直截了當,問題是將對象 Operator 保存到 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 EntityManagerpersist方法。

這是一些日志:

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 notrespecting 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;

這是在 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。

使用 MySQL,只有這種方法對我有用:

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

Pascal 在他的回答中提到的其他 2 種方法對我不起作用。

對於使用 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 列,所以您必須手動添加這些注釋。

如果你正在使用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")

請確保 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;

由於您在創建數據庫時已將 id 定義為 int 類型,因此您也必須在模型類中使用相同的數據類型。 並且由於您已將 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...
}

與 pascal 回答相同,如果您出於某種原因需要使用 .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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM