Hibernateから重複エントリエラーを取得するのは、MySQLのせいですか?

StackOverflow https://stackoverflow.com/questions/1205748

質問

ほとんどが読み取り専用のデータベースアプリケーションで作業していますが、アプリケーション内のユーザーの動きを記録し、大量の書き込みを行うテーブルが1つあります。数千の書き込みごとに、エラーログに次のようないくつかの例外が表示されます。

[WARN][2009-07-30 11:09:20,083][org.hibernate.util.JDBCExceptionReporter] SQL Error: 1062, SQLState: 23000
[ERROR][2009-07-30 11:09:20,083][org.hibernate.util.JDBCExceptionReporter] Duplicate entry '17011' for key 1
[ERROR][2009-07-30 11:09:20,083][org.hibernate.event.def.AbstractFlushingEventListener] Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
  at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:94)
  at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
  at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)

対象のテーブルには次のスキーマがあります:

CREATE TABLE IF NOT EXISTS `my_table` (
  `id` int(11) NOT NULL,
  `data1` int(11) NOT NULL,
  `data2` int(11) NOT NULL,
  `timestamp` datetime default NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;

および対応するHibernateマッピングXML:

<hibernate-mapping>
  <class name="mycorp.MyClass" table="my_table">
    <id name="id" column="id" type="java.lang.Integer">
      <generator class="increment"/>
    </id>
    <property name="data1" column="data1" type="java.lang.Integer"/>
    <property name="data2" column="data2" type="java.lang.Integer"/>
    <property name="timestamp" column="timestamp" type="java.util.Date"/>
  </class>
</hibernate-mapping>

Webappコンテキストの番号をバージョンアップして、新しいバージョンのアプリケーションをシームレスにリリースするため、webappの複数のインスタンスが一度にデータベースに書き込む可能性は低いですが、可能です。したがって、Webブラウザーにキャッシュされた古いバージョンのアプリケーションを持つクライアントは、古いバージョンのサーバーにアクセスし、数週間後にアンデプロイします。

とにかく、これが問題だとは確信していませんが、ここで手元にあるMySQLとHibernateの間に同期の問題があるのではないかと疑っています。ジェネレーターをシーケンス、シーケンス、またはヒロに変更すると役立ちますか?また、MySQLでそのようなジェネレーターをセットアップする例を提供できる場合、オンラインリソースのほとんどがHibernateマニュアルのひどくミニマルな例から単純にコピーアンドペーストされるため、非常に役立ちます。

役に立ちましたか?

解決

同じテーブルに複数のプロセスが書き込みを行っている場合、増分は間違いなく悪いです。衝突が発生します。

これはMySQLであるため、最も簡単に使用できるのは identity です。 Hibernateマッピング:

<generator class="identity"/>

MySQLスクリプト内:

CREATE TABLE IF NOT EXISTS `my_table` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `data1` int(11) NOT NULL,
  `data2` int(11) NOT NULL,
  `timestamp` datetime default NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;

既存のテーブルを変更するには:

ALTER TABLE `my_table`
  CHANGE COLUMN `id` `id` int(11) NOT NULL AUTO_INCREMENT=$NEW_VALUE$;

$ NEW_VALUE $は、シーケンスが1にリセットされないように、次に使用可能なIDに置き換える必要があります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top