使用 10k 条记录初始化 Grails 应用程序
Initialize Grails application with 10k records
我正在尝试使用一个域 class / table 的 10k 条记录作为初始数据集来初始化一个新的 Grails 应用程序。
挑战:
我不想通过数据库注入它们,因为我想让它们 运行 通过所有 Grails 验证器。
到目前为止我做了什么:
对于初始数据集,在我的开发 PC 上,我将它们注入数据库(通过 Talend Open Studio for Data Integration),然后生成 10k New
语句如下:
New Entity(prop1:'val1',prop2:'val2');
我已经在 Bootstrap 中尝试了数百个,效果很好。然后,我尝试使用其中的 10k 个,Groovy 编译器有时会堆栈跟踪 Class file too large
,有时它只是保持安静并停在那里。
基本思路是
if (Entity.count == 0) {
loadDataService.loadData()
}
我几乎不想承认,但我也尝试创建 10 个这样的服务,每个服务有 1000 条记录,并一个接一个地加载它们,但是 IDE 中的内存消耗正在达到 space 并且一切都停止了,有时它会通过并说 java.lang.RuntimeException: Method code too large!
(Java 方法中的 64kb 限制,这是有道理的)。
我还想到了什么:
看来只有使用Rest-API才能顺利搞定10k记录。但是对于那个功能,我必须付出努力来开发它,在我遇到另一个失败之前,我会听取你的建议。
问题:
我应该如何从这里开始?初始化应用程序的最佳方法是什么?
我已经解决了,感谢@Daniel and @elixir的帮助
在解决问题的过程中,我遇到了另一个问题:运行时在每条记录后大量增加记录,所以我不得不清除休眠会话。这样,运行时间就像“每 2-3 秒 100 条记录”,所以它是线性的。 This article on grails.asia提供了这部分的解决方案。
所以我得到了这段代码:
Bootstrap.groovy:
if (Entity.count == 0) {
println "No Entity found - Launch initial import"
loadDataService.loadData()
println "Initial import finished"
}
并在 loadDataService 中:
SessionFactory sessionFactory
def loadData() {
def inputFile = new File(grailsApplication.config.getProperty('importentitypath'))
def InputJSON = new JsonSlurper().parseFile(inputFile, 'UTF-8')
int mycounter = 0
InputJSON.each{
if (it.key=="data"){
it.value.each {myrow ->
mycounter+=1
if ((mycounter % 100) == 0 ) {
println mycounter
}
Entity.withNewTransaction {
Entity.findByRowkey(myrow.rowkey)?:new Entity(
rowkey:myrow.rowkey,
property1: myrow.property1,
property2: myrow.property2,
....
).save(failOnError:true, flush:true)
}
sessionFactory.currentSession.clear()
}
}
}
}
再次感谢您引导我找到那个解决方案!
我正在尝试使用一个域 class / table 的 10k 条记录作为初始数据集来初始化一个新的 Grails 应用程序。
挑战:
我不想通过数据库注入它们,因为我想让它们 运行 通过所有 Grails 验证器。
到目前为止我做了什么:
对于初始数据集,在我的开发 PC 上,我将它们注入数据库(通过 Talend Open Studio for Data Integration),然后生成 10k New
语句如下:
New Entity(prop1:'val1',prop2:'val2');
我已经在 Bootstrap 中尝试了数百个,效果很好。然后,我尝试使用其中的 10k 个,Groovy 编译器有时会堆栈跟踪 Class file too large
,有时它只是保持安静并停在那里。
基本思路是
if (Entity.count == 0) {
loadDataService.loadData()
}
我几乎不想承认,但我也尝试创建 10 个这样的服务,每个服务有 1000 条记录,并一个接一个地加载它们,但是 IDE 中的内存消耗正在达到 space 并且一切都停止了,有时它会通过并说 java.lang.RuntimeException: Method code too large!
(Java 方法中的 64kb 限制,这是有道理的)。
我还想到了什么:
看来只有使用Rest-API才能顺利搞定10k记录。但是对于那个功能,我必须付出努力来开发它,在我遇到另一个失败之前,我会听取你的建议。
问题:
我应该如何从这里开始?初始化应用程序的最佳方法是什么?
我已经解决了,感谢@Daniel and @elixir的帮助 在解决问题的过程中,我遇到了另一个问题:运行时在每条记录后大量增加记录,所以我不得不清除休眠会话。这样,运行时间就像“每 2-3 秒 100 条记录”,所以它是线性的。 This article on grails.asia提供了这部分的解决方案。
所以我得到了这段代码:
Bootstrap.groovy:
if (Entity.count == 0) {
println "No Entity found - Launch initial import"
loadDataService.loadData()
println "Initial import finished"
}
并在 loadDataService 中:
SessionFactory sessionFactory
def loadData() {
def inputFile = new File(grailsApplication.config.getProperty('importentitypath'))
def InputJSON = new JsonSlurper().parseFile(inputFile, 'UTF-8')
int mycounter = 0
InputJSON.each{
if (it.key=="data"){
it.value.each {myrow ->
mycounter+=1
if ((mycounter % 100) == 0 ) {
println mycounter
}
Entity.withNewTransaction {
Entity.findByRowkey(myrow.rowkey)?:new Entity(
rowkey:myrow.rowkey,
property1: myrow.property1,
property2: myrow.property2,
....
).save(failOnError:true, flush:true)
}
sessionFactory.currentSession.clear()
}
}
}
}
再次感谢您引导我找到那个解决方案!