0

我是使用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
4

2 回答 2

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
}

甚至更好的是使用服务类。但这可能是你的家庭作业。

于 2013-01-24T03:51:21.710 回答
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()
            }
        }
    }
于 2013-01-24T03:51:04.087 回答