Вставляет в базу данных сбой службы Grails

Я использую oracle11g в качестве базы данных и пытаюсь сделать вставки в таблицу globalusers из моего класса обслуживания grails. Я получаю источник данных в сервисе Grails следующим образом:

import org.codehaus.groovy.grails.commons.ApplicationHolder as AH 
class UserImportService {
 def dataSource = AH.application.mainContext.dataSource
 def sql = new Sql(dataSource) ;
 String insertQuery="insert into GLOBALUSERS (..) values (..)
                try{
                    sql.execute(insertQuery)
                }
                catch(Exception e){

                    println "Failed to insert : " +insertQuery
                    println "Exception is:" + e;

                }
}

Когда я запускаю службу из внешнего интерфейса, я получаю sql исключение, говорящее

Exception is:java.sql.SQLIntegrityConstraintViolationException: ORA-01400: cannot insert NULL into ("GRA"."GLOBALUSERS"."ID")

Так как я использую источник данных с моим собственным диалектом, который обрабатывает генерацию идентификаторов и автоинкремент, это должно быть обработано grail/hibernate.

Когда используется один и тот же источник данных из другого пользовательского интерфейса.. один за другим.. он работает.. так что диалект работает нормально. но этот сервис для пакетных обновлений не работает.

2 ответа

Решение

Делая прямой Sql на dataSource bean собирается обойти метод генерации идентификаторов Hibernate, который, насколько я понимаю, делает nextval() на соответствующей последовательности Oracle. Итак, ваши варианты:

  • Используйте Grails/GORM, где вы создаете объект, заполняете и .save()
  • Запросите последовательность самостоятельно, что потребовало бы выполнения nextval() на последовательности, но это сделает ваш Sql Oracle-специфичным
  • Добавьте триггер Oracle в базу данных, которая проверяет, установлен ли первичный ключ, и если он не установлен, nextval() запрос последовательности и добавляет его в новую строку базы данных. Это обеспечит совместимость вашего прямого Sql с автоинкрементами MySql и последовательностями Oracle.

Я не знаю Grails, но мне кажется, что

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