{"id":236,"date":"2009-09-09T16:43:32","date_gmt":"2009-09-09T11:13:32","guid":{"rendered":"http:\/\/www.tothenew.com\/blog\/?p=236"},"modified":"2009-09-14T13:04:34","modified_gmt":"2009-09-14T07:34:34","slug":"batch-processing-in-grails","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/batch-processing-in-grails\/","title":{"rendered":"Batch Processing In Grails"},"content":{"rendered":"<p> In one of my project assignments I needed to insert large number of records into the database. I had  to read the objects from an external source. Once I read all of the objects into a List, I iterated the list to save each one of them individually. In the beginning the process carried on fine but as the time passed the execution slowed down considerably. It almost took one second to insert one object into the database. Imagine the time it would have taken to insert 50000 records with this pace. Besides, many times it threw OutOfMemoryException. The code I had written did something like this :<\/p>\n<pre lang=\"groovy\"> (0..60000).each{\r\n           Person person = new Person(.....)\r\n           person.save()\r\n       }<\/pre>\n<p> One of the solutions that I found was to use transactions and save the objects in batches, each transaction saving a batch of objects. It worked  well and reduced the execution time considerably. What I did was like this :<\/p>\n<pre lang=\"groovy\">   def startTime = System.nanoTime()\r\n        List <Person> batch =[]\r\n        (0..50000).each{\r\n           Person person= new Person(....)\r\n            batch.add(person)\r\n            println \"Created:::::\"+it\r\n            if(batch.size()>1000){\r\n                Person.withTransaction{\r\n                    for(Person p in batch){\r\n                        p.save()\r\n                    }\r\n                }\r\n            }\r\n          batch.clear()\r\n          session = sessionFactory.getCurrentSession()\r\n          session.clear()\r\n        }\r\n        def endTime =  System.nanoTime()\r\n        def diff = (startTime-endTime)\/1000000000\r\n        println \"TIME TAKEN IS :::\"+diff<\/pre>\n<p> In the previous case the time take to save 50,000 records was around <em>500 seconds<\/em>. But, here time taken to save the same number of records came out to be just <em>80 seconds<\/em>.<\/p>\n<p> But there is one flaw in the method. If the objects are bulky, even this method would not work. Each action in a Grails Controller is executed within a Hibernate Session. The session is started right before the action starts and is closed once it returns. Thus Hibernate caches all the newly inserted Person instances in the session-level cache. As the number of objects grows, the session becomes bulkier, which slows down whole process .That also explains the reason for the memory issue, <em>OutOfMemoryException<\/em>, because all the objects are being cached to the Hibernate session.The solution to this problem is to clear the session regularly so as to keep it light throughout the process. All that needs to be done is to get hold of  the current session and clear it after each batch has been written to the database. To do this just inject SessionFactory object into your controller, get the current session object  and then clear this current session.<\/p>\n<pre lang=\"groovy\">\r\n        def startTime = System.nanoTime()\r\n        List <Person> batch =[]\r\n        (0..50000).each{\r\n           Person person= new Person(....)\r\n            batch.add(person)\r\n            println \"Created:::::\"+it\r\n            if(batch.size()>1000){\r\n                Person.withTransaction{\r\n                    for(Person p in batch){\r\n                        p.save()\r\n                    }\r\n                }\r\n                batch.clear()\r\n            }\r\n          session = sessionFactory.getCurrentSession()\r\n          session.clear()             \r\n        }\r\n        def endTime =  System.nanoTime() \r\n        def diff = (startTime-endTime)\/1000000000\r\n        println \"TIME TAKEN IS :::\"+diff\r\n<\/pre>\n<p>Thank you,<br \/>\nImran Mir,<br \/>\nimran@intelligrape.com<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In one of my project assignments I needed to insert large number of records into the database. I had to read the objects from an external source. Once I read all of the objects into a List, I iterated the list to save each one of them individually. In the beginning the process carried on [&hellip;]<\/p>\n","protected":false},"author":6,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":56,"footnotes":""},"categories":[7],"tags":[129,124,128,4840,127],"class_list":["post-236","post","type-post","status-publish","format-standard","hentry","category-grails","tag-batch-insertion","tag-batch-processing","tag-clear-hibernate-session","tag-grails","tag-slow-insertion"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.0.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"In one of my project assignments I needed to insert large number of records into the database. I had to read the objects from an external source. Once I read all of the objects into a List, I iterated the list to save each one of them individually. In the beginning the process carried on\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Imran Mir\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/www.tothenew.com\/blog\/batch-processing-in-grails\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.0.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"TO THE NEW BLOG\" \/>\n\t\t<meta property=\"og:type\" content=\"blog\" \/>\n\t\t<meta property=\"og:title\" content=\"Batch Processing In Grails | TO THE NEW Blog\" \/>\n\t\t<meta property=\"og:description\" content=\"In one of my project assignments I needed to insert large number of records into the database. I had to read the objects from an external source. Once I read all of the objects into a List, I iterated the list to save each one of them individually. In the beginning the process carried on\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/www.tothenew.com\/blog\/batch-processing-in-grails\/\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/www.tothenew.com\/blog\/wp-content\/themes\/ttn\/images\/social-logo.png\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/www.tothenew.com\/blog\/wp-content\/themes\/ttn\/images\/social-logo.png\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:site\" content=\"@tothenew\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Batch Processing In Grails | TO THE NEW Blog\" \/>\n\t\t<meta name=\"twitter:description\" content=\"In one of my project assignments I needed to insert large number of records into the database. I had to read the objects from an external source. Once I read all of the objects into a List, I iterated the list to save each one of them individually. In the beginning the process carried on\" \/>\n\t\t<meta name=\"twitter:image\" content=\"https:\/\/www.tothenew.com\/blog\/wp-content\/themes\/ttn\/images\/social-logo.png\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.tothenew.com\\\/blog\\\/batch-processing-in-grails\\\/#article\",\"name\":\"Batch Processing In Grails | TO THE NEW Blog\",\"headline\":\"Batch Processing In Grails\",\"author\":{\"@id\":\"https:\\\/\\\/www.tothenew.com\\\/blog\\\/author\\\/imran\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/www.tothenew.com\\\/blog\\\/#organization\"},\"datePublished\":\"2009-09-09T16:43:32+05:30\",\"dateModified\":\"2009-09-14T13:04:34+05:30\",\"inLanguage\":\"en-US\",\"commentCount\":6,\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.tothenew.com\\\/blog\\\/batch-processing-in-grails\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.tothenew.com\\\/blog\\\/batch-processing-in-grails\\\/#webpage\"},\"articleSection\":\"Grails, batch insertion, batch processing, clear hibernate session, Grails, slow insertion\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.tothenew.com\\\/blog\\\/batch-processing-in-grails\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.tothenew.com\\\/blog#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.tothenew.com\\\/blog\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.tothenew.com\\\/blog\\\/category\\\/grails\\\/#listItem\",\"name\":\"Grails\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.tothenew.com\\\/blog\\\/category\\\/grails\\\/#listItem\",\"position\":2,\"name\":\"Grails\",\"item\":\"https:\\\/\\\/www.tothenew.com\\\/blog\\\/category\\\/grails\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.tothenew.com\\\/blog\\\/batch-processing-in-grails\\\/#listItem\",\"name\":\"Batch Processing In Grails\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.tothenew.com\\\/blog#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.tothenew.com\\\/blog\\\/batch-processing-in-grails\\\/#listItem\",\"position\":3,\"name\":\"Batch Processing In Grails\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.tothenew.com\\\/blog\\\/category\\\/grails\\\/#listItem\",\"name\":\"Grails\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.tothenew.com\\\/blog\\\/#organization\",\"name\":\"TO THE NEW Blog\",\"url\":\"https:\\\/\\\/www.tothenew.com\\\/blog\\\/\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.tothenew.com\\\/blog\\\/author\\\/imran\\\/#author\",\"url\":\"https:\\\/\\\/www.tothenew.com\\\/blog\\\/author\\\/imran\\\/\",\"name\":\"Imran Mir\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/www.tothenew.com\\\/blog\\\/batch-processing-in-grails\\\/#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/186fa1c29a61225f60e52068be3f954d58ffa64750eac981d45154a72275b1eb?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"Imran Mir\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.tothenew.com\\\/blog\\\/batch-processing-in-grails\\\/#webpage\",\"url\":\"https:\\\/\\\/www.tothenew.com\\\/blog\\\/batch-processing-in-grails\\\/\",\"name\":\"Batch Processing In Grails | TO THE NEW Blog\",\"description\":\"In one of my project assignments I needed to insert large number of records into the database. I had to read the objects from an external source. Once I read all of the objects into a List, I iterated the list to save each one of them individually. In the beginning the process carried on\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.tothenew.com\\\/blog\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.tothenew.com\\\/blog\\\/batch-processing-in-grails\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/www.tothenew.com\\\/blog\\\/author\\\/imran\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/www.tothenew.com\\\/blog\\\/author\\\/imran\\\/#author\"},\"datePublished\":\"2009-09-09T16:43:32+05:30\",\"dateModified\":\"2009-09-14T13:04:34+05:30\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.tothenew.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.tothenew.com\\\/blog\\\/\",\"name\":\"TO THE NEW Blog\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.tothenew.com\\\/blog\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Batch Processing In Grails | TO THE NEW Blog","description":"In one of my project assignments I needed to insert large number of records into the database. I had to read the objects from an external source. Once I read all of the objects into a List, I iterated the list to save each one of them individually. In the beginning the process carried on","canonical_url":"https:\/\/www.tothenew.com\/blog\/batch-processing-in-grails\/","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.tothenew.com\/blog\/batch-processing-in-grails\/#article","name":"Batch Processing In Grails | TO THE NEW Blog","headline":"Batch Processing In Grails","author":{"@id":"https:\/\/www.tothenew.com\/blog\/author\/imran\/#author"},"publisher":{"@id":"https:\/\/www.tothenew.com\/blog\/#organization"},"datePublished":"2009-09-09T16:43:32+05:30","dateModified":"2009-09-14T13:04:34+05:30","inLanguage":"en-US","commentCount":6,"mainEntityOfPage":{"@id":"https:\/\/www.tothenew.com\/blog\/batch-processing-in-grails\/#webpage"},"isPartOf":{"@id":"https:\/\/www.tothenew.com\/blog\/batch-processing-in-grails\/#webpage"},"articleSection":"Grails, batch insertion, batch processing, clear hibernate session, Grails, slow insertion"},{"@type":"BreadcrumbList","@id":"https:\/\/www.tothenew.com\/blog\/batch-processing-in-grails\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/www.tothenew.com\/blog#listItem","position":1,"name":"Home","item":"https:\/\/www.tothenew.com\/blog","nextItem":{"@type":"ListItem","@id":"https:\/\/www.tothenew.com\/blog\/category\/grails\/#listItem","name":"Grails"}},{"@type":"ListItem","@id":"https:\/\/www.tothenew.com\/blog\/category\/grails\/#listItem","position":2,"name":"Grails","item":"https:\/\/www.tothenew.com\/blog\/category\/grails\/","nextItem":{"@type":"ListItem","@id":"https:\/\/www.tothenew.com\/blog\/batch-processing-in-grails\/#listItem","name":"Batch Processing In Grails"},"previousItem":{"@type":"ListItem","@id":"https:\/\/www.tothenew.com\/blog#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/www.tothenew.com\/blog\/batch-processing-in-grails\/#listItem","position":3,"name":"Batch Processing In Grails","previousItem":{"@type":"ListItem","@id":"https:\/\/www.tothenew.com\/blog\/category\/grails\/#listItem","name":"Grails"}}]},{"@type":"Organization","@id":"https:\/\/www.tothenew.com\/blog\/#organization","name":"TO THE NEW Blog","url":"https:\/\/www.tothenew.com\/blog\/"},{"@type":"Person","@id":"https:\/\/www.tothenew.com\/blog\/author\/imran\/#author","url":"https:\/\/www.tothenew.com\/blog\/author\/imran\/","name":"Imran Mir","image":{"@type":"ImageObject","@id":"https:\/\/www.tothenew.com\/blog\/batch-processing-in-grails\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/186fa1c29a61225f60e52068be3f954d58ffa64750eac981d45154a72275b1eb?s=96&d=mm&r=g","width":96,"height":96,"caption":"Imran Mir"}},{"@type":"WebPage","@id":"https:\/\/www.tothenew.com\/blog\/batch-processing-in-grails\/#webpage","url":"https:\/\/www.tothenew.com\/blog\/batch-processing-in-grails\/","name":"Batch Processing In Grails | TO THE NEW Blog","description":"In one of my project assignments I needed to insert large number of records into the database. I had to read the objects from an external source. Once I read all of the objects into a List, I iterated the list to save each one of them individually. In the beginning the process carried on","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/www.tothenew.com\/blog\/#website"},"breadcrumb":{"@id":"https:\/\/www.tothenew.com\/blog\/batch-processing-in-grails\/#breadcrumblist"},"author":{"@id":"https:\/\/www.tothenew.com\/blog\/author\/imran\/#author"},"creator":{"@id":"https:\/\/www.tothenew.com\/blog\/author\/imran\/#author"},"datePublished":"2009-09-09T16:43:32+05:30","dateModified":"2009-09-14T13:04:34+05:30"},{"@type":"WebSite","@id":"https:\/\/www.tothenew.com\/blog\/#website","url":"https:\/\/www.tothenew.com\/blog\/","name":"TO THE NEW Blog","inLanguage":"en-US","publisher":{"@id":"https:\/\/www.tothenew.com\/blog\/#organization"}}]},"og:locale":"en_US","og:site_name":"TO THE NEW BLOG","og:type":"blog","og:title":"Batch Processing In Grails | TO THE NEW Blog","og:description":"In one of my project assignments I needed to insert large number of records into the database. I had to read the objects from an external source. Once I read all of the objects into a List, I iterated the list to save each one of them individually. In the beginning the process carried on","og:url":"https:\/\/www.tothenew.com\/blog\/batch-processing-in-grails\/","og:image":"https:\/\/www.tothenew.com\/blog\/wp-content\/themes\/ttn\/images\/social-logo.png","og:image:secure_url":"https:\/\/www.tothenew.com\/blog\/wp-content\/themes\/ttn\/images\/social-logo.png","twitter:card":"summary","twitter:site":"@tothenew","twitter:title":"Batch Processing In Grails | TO THE NEW Blog","twitter:description":"In one of my project assignments I needed to insert large number of records into the database. I had to read the objects from an external source. Once I read all of the objects into a List, I iterated the list to save each one of them individually. In the beginning the process carried on","twitter:image":"https:\/\/www.tothenew.com\/blog\/wp-content\/themes\/ttn\/images\/social-logo.png"},"aioseo_meta_data":{"post_id":"236","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"Article","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"limit_modified_date":false,"created":"2021-04-29 11:55:36","updated":"2024-02-29 08:14:46","focus_keyword":null,"additional_keywords":null,"truseo_locale":null,"ai":null,"breadcrumb_settings":null,"seo_analyzer_scan_date":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.tothenew.com\/blog\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.tothenew.com\/blog\/category\/grails\/\" title=\"Grails\">Grails<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tBatch Processing In Grails\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/www.tothenew.com\/blog"},{"label":"Grails","link":"https:\/\/www.tothenew.com\/blog\/category\/grails\/"},{"label":"Batch Processing In Grails","link":"https:\/\/www.tothenew.com\/blog\/batch-processing-in-grails\/"}],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/236","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=236"}],"version-history":[{"count":0,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/236\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=236"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=236"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=236"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}