2010-09-12 73 views
3

我們與其中包含的服務的插件應用程序:服務在春季/ resources.groovy配置沒有一個Hibernate會話

public class TaskService { 

    public void doSomething(Task task) { 
     // do something with task 
     task.save(); 
    } 
} 

這工作得很好。


對於我們的「特殊」的顧客與他的特殊要求,我們有一個包含從第一個應用程序,並與該客戶的延伸原有服務和特殊服務的另一個插件的插件第二個應用程序重寫一些方法:

public class SpecialTaskService extends TaskService{ 

    @Override 
    public void doSomething(Task task) { 
     // do something special with task 
     task.save(); 
    } 
} 

在第二個應用程序的每處地方taskService注入,我們希望有SpecialTask​​Service現在(也從第一個應用程序的插件)。在特殊的服務

beans = { 
     taskService(SpecialTaskService) 
} 

但現在我們得到了一個HibernateException的時候我們稱之爲「task.save()」:因此,我們下的grails-app/conf目錄/春加入特殊服務的resources.groovy org.hibernate.HibernateException:沒有Hibernate Session綁定到線程,並且配置不允許創建非事務性的一個在這裏

我們知道我們可以將一個SessionFactory注入到SpecialService中,但是當我們調用sessionFactory.currentSession時,同樣的例外。

當我們在resources.groovy中配置一個不擴展另一個的服務時,也會發生異常。

有沒有辦法讓特殊服務某種「hibernateSessionAware」,以便我們可以調用域對象上的save()和merge()?

回答

5

原始服務是事務性的,所以它在方法調用期間保持Hibernate會話打開(除非一個已經激活並且已經加入)。所以,你需要讓你的事務太多,因爲你只是告訴春與taskService(SpecialTaskService)

做(如果你喜歡或個人的方法)的註釋類最簡單的事情創建一個純新實例:

import org.springframework.transaction.annotation.Transactional 

@Transactional 
class SpecialTaskService extends TaskService { 

    @Override 
    void doSomething(Task task) { 
     // do something special with task 
     task.save() 
    } 
} 

但您也可以將代碼塊或整個方法包裝在withTransaction塊中:

class SpecialTaskService extends TaskService { 

    @Override 
    void doSomething(Task task) { 
     Task.withTransaction { status -> 
     // do something special with task 
     task.save() 
     } 
    } 
}