MySQL виноват в получении повторяющихся ошибок ввода из Hibernate?

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

Вопрос

Я работаю над приложением базы данных, которое в основном доступно только для чтения, но есть одна таблица, в которой записывается движение пользователя в приложении, и в него записывается большое количество записей. Для каждых нескольких тысяч записей мы видим несколько исключений в журнале ошибок, например:

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

И соответствующий XML-код отображения Hibernate.

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

Возможно, хотя и маловероятно, что несколько экземпляров нашего веб-приложения могут одновременно записывать данные в базу данных, поскольку номера версий в контексте нашего веб-приложения позволяют беспрепятственно выпускать новые версии приложений. Таким образом, клиенты со старой версией приложения, кэшированной в веб-браузере, получат доступ к старым версиям сервера, которые мы удаляем через несколько недель.

В любом случае, я не уверен, что это проблема, но я подозреваю, что здесь есть какая-то проблема синхронизации между MySQL и Hibernate. Поможет ли изменение моего генератора в последовательности, seqhilo или hilo? Кроме того, если вы можете привести пример настройки такого генератора в 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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top