I need to update a single property on a large set of data in Oracle database with grails 2.5
Right now my code looks similarly to this:
List booksToUpdate = []
boolean moreBooks = true
int offset = 0
while (moreBooks) {
def fetchedBooks = []
if('Europe'){
fetchedBooks = Book.findAllByAuthorInList(getEuropeanAuthors(),
[max: BATCHSIZE, offset: offset])
} else {
fetchedBooks = Book.findAllByAuthorInListAndPublishYear(getEnglishAuthors(), '1999',
[max: BATCHSIZE, offset: offset])
}
booksToUpdate.addAll(fetchedBooks)
moreBooks = fetchedBooks.size() == BATCHSIZE
offset += BATCHSIZE
}
booksToUpdate.each { book ->
book.copyright = '2020'
book.save(flush: true, failOnError: true)
}
I would like to batch my updates for performance. Also, findAll query differs very slightly and it would be nice to build search criteria condifitionally. Ideally I want something like this:
while (moreBooks) {
def fetchedBooks = []
def criteria = new DetachedCriteria(Book)
criteria.build [max: BATCHSIZE, offset: offset] {
List relevantAuthors = []
if('Europe') {
relevantAuthors = getEuropeanAuthors()
eq 'publishYear', '1999'
} else {
relevantAuthors = getEnglishAuthors()
}
inList 'author', relevantAuthors
}
criteria.updateAll(copyright:'2020') //batch update
moreBooks = fetchedBooks.size() == BATCHSIZE
offset += BATCHSIZE
}
Is there a way to do this? Doesn't have to be with DetachedCriteria. I looked at the guide but I can't find anything about passing max and offset. Is there a better way to make the code more elegant without compromising its performance?