sobota 31. března 2012

Bootstrap.groovy a velké množství počátečních dat

Dnes se mi podařilo vyřešit problém, který jsem ani nedoufal, že se dá vyřešit. Problém spočíval v tom, že v bootstrap souboru v Grailsu zkouším vytvářet velké množství testovacích dat - celý soubor má cca 1000 řádků. Jenže při spuštění Grails hlásil divnou chybu:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x000000000262b036, pid=4152, tid=8016
#
# JRE version: 6.0_29-b11
# Java VM: Java HotSpot(TM) 64-Bit Server VM (20.4-b02 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# j  BootStrap$_closure1.doCall(Ljava/lang/Object;)Ljava/lang/Object;+87
#
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp
#

---------------  T H R E A D  ---------------

Current thread (0x000000000d985800):  JavaThread "pool-7-thread-1" [_thread_in_Java, id=8016, stack(0x000000000bcf0000,0x000000000bdf0000)]

siginfo: ExceptionCode=0xc0000005, reading address 0x0000000138c797cf

Registers:
RAX=0x000000000bdedd78, RBX=0x000000000bdedd78, RCX=0x00000000d9d1e488, RDX=0x00000000d9d0abff
RSP=0x000000000bdedd88, RBP=0x000000000bdeddb8, RSI=0x000000000d985800, RDI=0x000000000ee83ed0
R8 =0x0000000000000004, R9 =0x00000000d4b4e890, R10=0x000000006dfc4f80, R11=0x000000000ee83f38
R12=0x0000000000000000, R13=0x00000000d9d1d8ce, R14=0x000000000bdee5b0, R15=0x000000000d985800
RIP=0x000000000262b036, EFLAGS=0x0000000000010287

Když jsem ten dlouhej soubor okomentoval zhruba tak 3/4, tak vše jelo. Prvně jsem si myslel, že je to chyba v nedostatku paměti JVM. Zkoušel jsem tedy zvýšit paměť ze 128MB na 512 MB. Chyba však stále byla. Druhé, co mě pak napadlo, byla ne nejnovější verze JVM. Měl jsem 1.6-něco-29 a nejnovější bylo asi 1.6.-něco-31. Updatoval jsem, ale chyba tu furt byla. Už jsem to docela vzdal a smířil jsem se s tím, že prostě budu mít míň testovacích dat, stejně who cares.

Včera jsem však kouknul zpátky na StackOverflow, kam jsem položil otázku na tento problém. Nějakej týpek napsal, ať zkusím rozdělit soubor do více transakcí. Za chvíli jsem našel konstrukci, která to provádí:


Patient.withTransaction {

// vytváření a ukládání doménových tříd…

}


Najednou chyba už nebyla Veselý obličej Jen pak byl problém s tím, že se ukládaly jen 50 entit. Pak jsem zjistil, že se tedy musí dávat .save(flush:true) na konec té transakce, aby se uložila. Také je nutné, aby na sebe odkazující entity byly v jedné transakci. A to je celé Veselý obličej

Žádné komentáře:

Okomentovat