Вставляет в базу данных сбой службы 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 полностью обходит создание идентификаторов. Для автоматической генерации идентификатора вам нужно будет создать экземпляр и сохранить сущность.