web-dev-qa-db-ja.com

MYSQL自動インクリメントフィールドにJPAアノテーションを付ける方法

要するに、問題はオブジェクト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はMySQL auto_increment主キーフィールドを尊重しません しかし、それは何も機能しませんでした

他の構成ファイルが必要な場合は、それらを提供します。

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`)
)
96
trivunm

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のinsertステートメントのid列を省略する必要がありますが、そうではありません。どこかにある種の不一致がなければなりません。

Hibernate構成でMySQLダイアレクトを指定しましたか(使用しているエンジンに応じてMySQL5InnoDBDialectまたはMySQL5Dialect)。

また、誰がテーブルを作成しましたか?対応するDDLを表示できますか?

フォローアップ:問題を再現できません。 Hibernateは、yourエンティティとyourDDLのコードを使用して、以下を生成します(予想)MySQLを使用したSQL:

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

予想どおり、id列は上記のステートメントにはないことに注意してください。

まとめると、コード、テーブル定義、および方言は正しく、一貫性があり、動作するはずです。うまくいかない場合は、何かが同期していない(クリーンビルドを実行する、ビルドディレクトリをダブルチェックするなど)か、何か他のものが間違っている(疑わしい点がないかログを確認してください)。

方言に関しては、MySQL5DialectまたはMySQL5InnoDBDialectonlyの違いは、後でENGINE=InnoDBがテーブルに追加されることです。 DDLを生成するときのオブジェクト。どちらを使用しても、生成されたSQLは変更されません。

131
Pascal Thivent

MySQLを使用すると、このアプローチのみが機能していました。

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

パスカルが彼の答えで述べた他の2つのアプローチは、私にとってはうまくいきませんでした。

30
Jelle

EclipseLink for JPA 2.0を使用しているこれを読んでいる人のために、JPAにデータを永続化させるために使用しなければならなかった2つの注釈があります。ここで、「MySequenceGenerator」シーケンスオブジェクトを含むデータベース内のスキーマ。「mysequence」はデータベース内のシーケンスオブジェクトの名前です。

@GeneratedValue(strategy= GenerationType.SEQUENCE, generator="MySequenceGenerator")
@SequenceGenerator(allocationSize=1, schema="myschema",  name="MySequenceGenerator", sequenceName = "mysequence")

EclipseLink(および場合によっては他のJPAプロバイダー)を使用している場合、データベースのシーケンスに定義されたINCREMENT値と一致するように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

また、遅延のために、DBからエンティティ、エンティティからコントローラ、およびエンティティからJSFを生成するウィザードを使用してこれをNetbeansで構築しました。これらの注釈を手動で追加する必要があります。

12
Max Awesome

Idデータ型がStringではなくLongであることを確認してください。それが文字列の場合、@ 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))
5
ABHAY JOHRI

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")
1
dmarquina

データベースの作成時にint型でidを定義したため、モデルクラスでも同じデータ型を使用する必要があります。データベースでIDを自動インクリメントするように定義したので、アノテーション@GeneratedValue内の属性 'strategy'に値 'GenerationType.AUTO'を渡すことにより、モデルクラスでそれを言及する必要があります。次に、コードは次のようになります。

@Entity
public class Operator{

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private int id;

  private String username;

  private String password;

  private Integer active;

  //Getters and setters...
}
0
Anjali Pavithra

私はすべてを試しましたが、それでもできませんでした、mysql、jpaをhibernateで使用しています、コンストラクタでid 0の値を割り当てることで問題を解決しました

@Id
@Column(name="id",updatable=false,nullable=false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

正しいデータベースに接続したかどうかを確認できますか。私は同じ問題に直面していましたが、最終的に私は別のデータベースに接続していることがわかりました。

identityは、DB2、MySQL、MS SQL Server、Sybase、およびHypersonicSQLのID列をサポートします。返される識別子は、long、short、またはint型です。

詳細: http://docs.jboss.org/hibernate/orm/3.5/reference/en/html/mapping.html#mapping-declaration-id

0
Mohan Reddy