2014-06-16 64 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/开始 –