dagilmore
dagilmore

Reputation: 35

Grails + hibernate + controller sessionFactory null object?

I am new to using hibernate and grails. I have multiple java objects that I need to persist. To learn how it works I'm using a simple example of an employee class. Its in my src/java with the corresponding xml mappings with it. I think I need to make a session instance from my session factory, and I do not know what I'm doing wrong. I followed a tutorial for setting up hibternate hibernate tut and tried to translate it for grails. Any thoughts?

package com.turingpages.Matrix.view

import org.springframework.dao.DataIntegrityViolationException
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.codehaus.groovy.grails.commons.ApplicationHolder as AH


class MatrixController {

    def ctx = AH.application.mainContext
    def sessionFactory = ctx.sessionFactory

    static allowedMethods = [save: "POST", update: "POST", delete: "POST"]

...

    def create() {
        def session = sessionFactory.currentSession
        Transaction tx = null;
        Integer employeeID = null;
        try{
            tx = session.beginTransaction();
            Employee employee = new Employee("fname", "lname", 100);
            employeeID = (Integer) session.save(employee);
            tx.commit();
        } catch (HibernateException e) {
            if (tx!=null) tx.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }
        return employeeID;
    }

My stack trace:

 ERROR errors.GrailsExceptionResolver  - NullPointerException occurred when processing request: [POST] /turingpages/matrix/create
Cannot get property 'currentSession' on null object. Stacktrace follows:
Message: Cannot get property 'currentSession' on null object
    Line | Method
->>   33 | create    in com.turingpages.Matrix.view.MatrixController$$ENvP7skK
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|    195 | doFilter  in grails.plugin.cache.web.filter.PageFragmentCachingFilter
|     63 | doFilter  in grails.plugin.cache.web.filter.AbstractFilter
|   1110 | runWorker in java.util.concurrent.ThreadPoolExecutor
|    603 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^    722 | run       in java.lang.Thread

Upvotes: 0

Views: 2260

Answers (2)

Gregg
Gregg

Reputation: 35864

There's no reason you should be writing code like that with Grails. If you really need to manage the transaction in a controller, you should do it this way.

def create() {
    Integer employeeID = null;
    Employee.withTransaction { status ->
      Employee employee = new Employee(firstName: "fname", lastName: "lname", noIdea: 100);
      employee.save()
      if (employee.hasErrors()) {
         status.setRollbackOnly()
      }
    }
    return employee.id;
}

That said, when dealing with a single Domain like this, you don't really need to worry about it at all:

def create() {
   Employee employee = new Employee(firstName: "fname", lastName: "lname", noIdea: 100);
   employee.save(flush: true)
   [employee: employee] // generally you want to pass the object back to a view this way
   // deal with errors in the domain on the view
}

And even better would be to use a Service class. But that can be your homework assignment.

Upvotes: 1

coderLMN
coderLMN

Reputation: 3076

You need to move the code

def ctx = AH.application.mainContext
def sessionFactory = ctx.sessionFactory

into the method create(), or replace it with

def sessionFactory

However, Grails provides a withTransaction method to serve your purpose in a simpler way:

    def create() {
        Employee.withTransaction{ status ->
            Employee employee = new Employee("fname", "lname", 100).save()
            .....
            if (employee.id) {
                return employee.id
            }
            else {
               status.setRollbackOnly()
            }
        }
    }

Upvotes: 0

Related Questions