2016-02-04 65 views
0

我遇到以下代碼的問題,請我需要幫助。 在使用Hibernate的服務層中,我使用註釋來管理會話,這非常有效。Java和休眠 - 使用接口時的會話管理

@Override 
@Transactional 
public Response delete(Integer id) throws Exception { 
    Response response = new Response(); 
    try { 
     response.setData(videoDao.delete(id)); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return response; 
} 

它調用了DAO層

@Override 
    public boolean delete(int id) throws Exception { 
     String query = "UPDATE " + this.entity + 
       " SET remove_date = '" + String.valueOf(new Date(0)) + "'" + 
       " WHERE id = " + id; 
     Query q = sessionFactory.getCurrentSession().createQuery(query); 
     return q.executeUpdate() > 0 ? true : false; 
     } 

哪裏videoDao是實現接口的實體DAO層下面的方法。到現在爲止還挺好。

問題是,當我有另一種方法在videoDao不在我正在實現的接口中,在這種情況下,註釋不起作用,但我不知道如何管理服務層中的sessionFactory。我想我在使用接口中的方法時沒有問題,因爲Spring注入的是包含sessionFactory的istances,但是如果我手動執行它(因爲我不能使用注入的對象,因爲它是接口,而不是具有此方法的真實類)sessionFactory始終爲空。

public interface IDao { 
    public boolean delete(int id) throws Exception; 
} 

這是我如何定義與接口的刀在我的服務層:

@Autowired 
IDao videoDao; 
+1

你能顯示代碼示例有關此主題的更多信息,您導致空SessionFactory的? –

+2

@Faabass既然你正在自動裝配'IDao videoDao',你怎麼能夠調用接口中沒有指定的另一個方法呢? –

+0

你是什麼意思'註釋不起作用'?請發佈您的videoDAO類的代碼,並與非繼承的方法,據說不工作 – yugo

回答

0

總之我對你所尋找的理解 - 你想在定義的方法春天代理類而不是由該類實現的接口中定義的方法。

有了上述假設,您正在觀察的行爲與Spring AOP代理生成一致。

Spring AOP的代理生成默認用途:

  1. JDK動態代理,如果目標類實現了至少一個接口。

  2. CGLIB代理如果目標類沒有實現任何接口。

所以對於JDK代理,Spring AOP使用目標接口來查找需要代理的方法。 Spring JDK代理只實現接口中定義的方法。因此,如果有任何方法直接在目標類中定義,而不是在接口中定義,那麼這些方法將不會被代理,並且這是您正在觀察的行爲。

使用CGLIB選項,只有當目標類沒有實現任何接口時,Spring纔會生成CGLIB代理。這個CGLIB代理擴展了目標類,因此代理了目標類中的方法。

這是默認行爲。

但是如果我們想通知Spring甚至爲基於接口的目標類生成CGLIB代理,我們可以通過使用proxy-target-class=trueproxyTargetClass屬性來實現。有了這個Spring AOP代理了類中定義的方法,而不是查看接口,我推測這就是你正在尋找的。

正如你已經指出的,爲了這個工作,我們需要在代碼中使用/注入類而不是接口,儘管不是最佳實踐。

您可以在http://docs.spring.io/spring/docs/4.3.0.BUILD-SNAPSHOT/spring-framework-reference/htmlsingle/#aop-proxyinghttp://docs.spring.io/spring/docs/4.3.0.BUILD-SNAPSHOT/spring-framework-reference/htmlsingle/#transaction