0

私は休止状態とグレイルを使用するのが初めてです。永続化する必要がある 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
}

さらに良いのは、Serviceクラスを使用することです。しかし、それはあなたの宿題になる可能性があります。

于 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 に答える