Grails + hibernate + controller sessionFactory null对象?

时间:2013-01-24 03:10:57

标签: spring hibernate model-view-controller grails orm

我是使用hibernate和grails的新手。我有多个需要持久保存的java对象。要了解它的工作原理,我将使用一个简单的员工类示例。它在我的src / java中与它对应的xml映射。我想我需要从会话工厂创建一个会话实例,我不知道我做错了什么。我按照教程设置了hibternate hibernate tut并尝试将其翻译为grails。有什么想法吗?

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;
    }

我的堆栈跟踪:

 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

2 个答案:

答案 0 :(得分:1)

没有理由你应该用Grails编写这样的代码。如果你真的需要在控制器中管理事务,你应该这样做。

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;
}

那就是说,在处理像这样的单个域名时,你根本不需要担心它:

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
}

更好的方法是使用Service课程。但这可能是你的家庭作业。

答案 1 :(得分:0)

您需要移动代码

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

进入方法create(),或用

替换它
def sessionFactory

但是,Grails提供withTransaction方法以更简单的方式为您的目的服务:

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