2014-06-16 79 views
0

我從DAO方法和sessionFactory中刪除static。現在IDE使我轉回使用靜態DAO方法,因爲它說Non-static method updatePrice(long) cannot be referenced form a static context。這兩個類都不包含靜態關鍵字。怎麼了?如何解決它?什麼春天與靜態上下文

ServiceActionDAO

@Transactional 
public class ServiceActionDAO{ 
@Autowired 
    SessionFactory sessionFactory; 

public void insert(ServiceActionEntity paramServiceAction){ 
     Transaction localTransaction = null; 
     try{ 
      Session localSession = sessionFactory.getCurrentSession(); 
      localSession.save(paramServiceAction); 
      localSession.getTransaction().commit(); 
ServiceOrderDAO.updatePrice(paramServiceAction.getServiceOrderFk().longValue());// error 
     } 
     catch (Exception localException){ 
      if (localTransaction != null) { 
       localTransaction.rollback(); 
      } 
     } 
    } 

UPDATE

我找到一個快速的方法通過更換錯誤行來解決這個問題:

new ServiceOrderDAO().updatePrice(paramServiceAction.getServiceOrderFk().longValue()); 

現在,它不是一個靜態調用。


UPDATE 2

我有很多DAO類和多個控制器。考慮到Spring架構,我必須儘快修復最小代碼更改。我有一個DAO調用一個或多個DAO來執行一些複雜的查詢。

正如之前所述:創建DAO的新實例會導致不可預知的Spring會話行爲。

看來我的控制器也有DAO類的調用。

解決這個問題最簡單的方法是什麼(用最少的代碼修改)?


UPDATE 3

端向上注入到DAO的DAO和控制器。這似乎是速戰速決,但是從概念觀點我懷疑,這是最好的解決辦法...

+1

'updatePrice'不是'靜態'方法,但你試圖靜態調用它...請搜索錯誤消息。 –

+1

除非聲明常量,否則請儘量不要使用'static'。在所有其他情況下,避免它。你的Dao不應該是靜態的,它不應該有靜態方法。它是一個spring bean,需要用spring來實例化,以便事務方面可以將調用攔截到它的方法 - 如果它以任何方式靜態,這不會發生。 –

+0

你應該從春季開始(通常是將它注入你的控制器,或者直接引用spring的上下文)來獲得Dao。如果您按照以上所述創建新實例,那麼您的交易將無法工作。 –

回答

2

您可以

一)注入到你的ServiceOrderDAO到ServiceActionDao參考,並調用該方法在注入的DAO實例上,或者b)您可以引入一個服務層,在同一個事務中調用這兩個DAO,其中每個DAO都被注入服務。

無論哪種方式,你必須使兩個DAO彈簧管理的豆。

如果您遇到需要從另一個DAO調用一個DAO的情況,那麼引入一個服務似乎是一個合適的解決方案。

此外,提交和回滾是不必要的,甚至適得其反。使用Spring時,您應該可以毫無問題地移除此代碼。

製作DAO的新實例並不是一個很好的解決方案,因爲它不是Spring管理的bean。如果它具有自動裝配屬性,那麼它們將不會被設置。如果它使用自己的SessionFactory,與自動裝配的不同,那麼你會得到奇怪的行爲,因爲它將使用與Spring管理的DAO不同的會話。

+0

你能給我快速exampel代碼我怎麼可以讓** b)**?我有''所以我認爲我所有的DAO都是由spring管理的bean。對? –

+0

@RCola:您需要DAO上的存儲庫註釋。舉個例子,你可以從https://github.com/spring-projects/spring-petclinic/開始 –