2017-01-20 3 views
0

Я хотел бы знать, можете ли вы помочь мне с ошибкой, которую я получаю при вводе данных в базу данных из файла CSV.Захват сеанса гибернации Grails 3 вызывает NullPointerException

  • Grails 3.2.4
  • ява версия "1.8.0_111" Java (TM) SE Runtime Environment (сборка 1.8.0_111-b14) Java HotSpot (TM) 64-разрядного сервера VM (сборка 25,111-b14, смешанный режим)

  • Mysql 5.6.29

  • Hibernate 5.1.1

Дело в том, что я я читаю CSV-файл и обрабатываю его партиями. Поскольку зимуют кэширует все объекты в памяти, после определенного количества записей я делаю:

private void cleanUpGorm() { 
     def session = sessionFactory.currentSession 
     session.flush() 
     session.clear() 
} 

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

Дело в том, что с некоторыми CSV-файлами (4 из 15) я получаю исключение NullPointerException при вызове session.flush() (с сеансом не равным нулю). Эти файлы CSV не имеют странные вещи, кодирование в порядке, нет плохих символов и т.д.

У меня есть два метода:

@NotTransactional 
void loadDataFromCSV() { 
    // Group the CSV lines into groups of 1000. 
    loadBatch(myGroupOfLines) 
} 

// No annotation here.. I assume that by default is Transactional 
void loadBatch(myGroupOfLines) { 

    // Iterate over myGroupOfLines Inserting or updating the entries in the db. 

    // Clean GORM cache 
    if(index > 0 && index % CLEAN_GORM_CACHE_FREQUENCY == 0) { 
     log.info "**** Cleaning GORM cache ****" 
    cleanUpGorm() 
    } 
} 

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

Подробное NPE я получаю:

2017-01-19 18:00:52,440 - ERROR: GrailsExceptionResolver - NullPointerException occurred when processing request: [POST] /api/admin/upload - parameters: 
entity: OCEAN_COSTS 
Stacktrace follows: 
java.lang.reflect.InvocationTargetException: null 
     at org.grails.core.DefaultGrailsControllerClass$ReflectionInvoker.invoke(DefaultGrailsControllerClass.java:210) 
     at org.grails.core.DefaultGrailsControllerClass.invoke(DefaultGrailsControllerClass.java:187) 
     at org.grails.web.mapping.mvc.UrlMappingsInfoHandlerAdapter.handle(UrlMappingsInfoHandlerAdapter.groovy:90) 
     at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963) 
     at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) 
     at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) 
     at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872) 
     at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) 
     at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55) 
     at org.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:77) 
     at org.grails.web.filters.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:67) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
     at java.lang.Thread.run(Thread.java:745) 
Caused by: java.lang.NullPointerException: null 
     at org.hibernate.engine.spi.BatchFetchQueue.removeBatchLoadableEntityKey(BatchFetchQueue.java:147) 
     at org.hibernate.engine.internal.StatefulPersistenceContext.addEntity(StatefulPersistenceContext.java:387) 
     at org.hibernate.engine.internal.StatefulPersistenceContext.addEntity(StatefulPersistenceContext.java:462) 
     at org.hibernate.action.internal.AbstractEntityInsertAction.makeEntityManaged(AbstractEntityInsertAction.java:126) 
     at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:279) 
     at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:254) 
     at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:299) 
     at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:318) 
     at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:275) 
     at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:182) 
     at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:113) 
     at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:192) 
     at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:177) 
     at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:97) 
     at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73) 
     at org.grails.orm.hibernate.support.ClosureEventTriggeringInterceptor.onSaveOrUpdate(ClosureEventTriggeringInterceptor.java:81) 
     at org.hibernate.internal.SessionImpl.fireSaveOrUpdate(SessionImpl.java:651) 
     at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:643) 
     at org.hibernate.engine.spi.CascadingActions$5.cascade(CascadingActions.java:218) 
     at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:391) 
     at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:316) 
     at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:155) 
     at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:424) 
     at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:356) 
     at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:319) 
     at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:155) 
     at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:104) 
     at org.hibernate.event.internal.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:150) 
     at org.hibernate.event.internal.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:141) 
     at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:74) 
     at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:38) 
     at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1295) 
     at maersk.calculator.api.MaritimeTransportationService$$EQ8n1X8K.cleanUpGorm(MaritimeTransportationService.groovy:401) 
     at maersk.calculator.api.MaritimeTransportationService$__tt__loadBatch_closure10$$EQ8n1X8K.doCall(MaritimeTransportationService.groovy:227) 
     at maersk.calculator.api.MaritimeTransportationService$$EQ8n1X8K.$tt__loadBatch(MaritimeTransportationService.groovy:200) 
     at grails.transaction.GrailsTransactionTemplate$2.doInTransaction(GrailsTransactionTemplate.groovy:96) 
     at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133) 
     at grails.transaction.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:93) 
     at maersk.calculator.api.MaritimeTransportationService$$EQ8n1X8K.loadDataFromCSV(MaritimeTransportationService.groovy:139) 
     at maersk.calculator.api.UploadController.triggerJob(UploadController.groovy:88) 
     at maersk.calculator.api.UploadController.saveFile(UploadController.groovy:55) 
     ... 14 common frames omitted 

EDIT

Ну, на самом деле я мог бы изолировать проблему и он находится внутри метода loadBatch. Кажется, это связано с #9290

ошибка происходит в следующем фрагменте кода:

mtc = new MaritimeTransportationCharge(charge, amount, currency, container, mt) 
mt.addToCharges(mtc) 
if(!mt.save()) { 
    errors.add("Error in line $line: Invalid charge for container ${container}.\nErrors: ${Utils.getEntityErrors(mtc)}") 
} 

кажется, что ассоциации не выровнена больше (по состоянию на 2 Grails) и что-то происходит, возможно, дочерний объект недействителен.

Отношений являются:

MaritimeTransportation hasMany: MaritimeTransportationCharges 
MaritimeTransportationCharge belongsTo: MaritimeTransportation 

ответ

1

Я хотел бы предложить добавить протоколирование SQL в application.yml

environments: 
    local: 
    dataSource: 
     logSql: true 
     formatSql: true 

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

MaritimeTransportationCharges joinTable: [name:"join_table_name", key: "key", column: "column"] 
Смежные вопросы