Ограничение спящего режима. Ограничение исключения. Есть ли простой способ игнорировать повторяющиеся записи?

В принципе у меня есть приведенная ниже схема, и я вставляю записи, если они не существуют. Однако, когда дело доходит до вставки дубликата, это вызывает и ошибку, как я ожидал. Мой вопрос заключается в том, есть ли простой способ заставить Hibernate просто игнорировать вставки, которые в действительности вставляют дубликаты?

CREATE TABLE IF NOT EXISTS `method` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `name` (`name`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;


SEVERE: Duplicate entry 'GET' for key 'name'
Exception in thread "pool-11-thread-4" org.hibernate.exception.ConstraintViolationException: could not insert:

Ответы

Ответ 1

Мой вопрос заключается в том, есть ли простой способ заставить Hibernate просто игнорировать вставки, которые в действительности вставляют дубликаты?

Как Hibernate, возможно, знает, что запись имеет уникальное значение без фактической вставки записи?

Если вы делаете пакетные вставки и не хотите откатывать всю транзакцию и отбрасываете сеанс в случае ConstraintViolationException (то, что вы должны делать теоретически после исключения, см. этот поток и этот предыдущий ответ), моим предложением было бы использовать API StatelessSession и поймать ConstraintViolationException.

Ответ 2

Спящий режим не может этого сделать. Однако вы можете сделать это сами. По существу есть два варианта:

  • Проверить наличие дубликатов перед вставкой; или
  • Поймайте исключение ConstraintViolationException, а затем убедитесь, что это нарушение связано с дубликатом (поскольку могут быть другие причины, такие как пустые поля).

Первый имеет тот недостаток, что вы проверяете дубликаты на каждой вставке, когда вероятность того, что на самом деле существует дубликат, может быть низкой. Последний будет быстрее для обычного случая, когда дубликатов не происходит, но имеет тот недостаток, что вам нужно проверить дубликаты после лица. Когда генерируется исключение ConstraintViolationException, он отменяет текущую сессию; это означает, что вам нужно выполнить флеш перед выполнением поиска дубликата.

Проверка дубликатов перед вставкой - это, пожалуй, самый чистый подход, если не существует серьезной проблемы с производительностью, о которой вам нужно беспокоиться. Убедитесь, что вы выполняете поиск и вставляете транзакцию, чтобы убедиться, что кто-то не добавляет дубликат между поиском и вставкой, иначе вы получите исключение ConstraintViolationException.

Ответ 3

Как и Паскаль сказал, Hibernate не будет знать, является ли это дубликат, пока он не был фактически инкрустирован.

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

Ответ 4

Вместо использования createQuery() в спящем режиме используйте createSQLQuery() и попробуйте запрос типа "REPLACE INTO method (id) VALUES (123);"

Ответ 5

Вы можете попробовать поймать исключение org.hibernate.exception.ConstraintViolationException и усвоить исключение в своем коде

Например:

try {
    sessionFactory.getCurrentSession().saveOrUpdate(entity);
} catch (ConstraintViolationException e) {
    // Ignore the exception here by doing nothing
}

Ответ 6

даже если вы поймаете исключение, могут возникнуть другие проблемы.

try{
       session.save(O);
       session.getTransaction().commit();
    }catch (HibernateException e) {
       System.out.println("you are carched ¤#%SD¤") ;
    }

Ответ 7

Вы можете использовать аннотацию @SqlInsert для своей сущности, чтобы изменить использование hibernate sql для вставки в базу данных, в настоящее время hibernate должен использовать этот оператор

insert into method(name, id) values (?,?)

Если вы используете mysql, вы можете использовать оператор @SqlInsert для изменения вставки sql с помощью команды insert ignore mysql

@SQLInsert(sql = "insert ignore into method(name, id) values (?,?)")

Однако вы должны получить sqs-вставки, включив режим show sql в спящем режиме, поскольку порядок столбцов генерируется с помощью некоторой логики, и их документы предлагают этот способ.