2010-06-09 42 views
0

我發現這篇文章其中談到使用Spring作爲JPA容器:使用Spring的JPA容器

http://java.sys-con.com/node/366275

我從來沒有使用過Spring在此之前,我試圖使這項工作,並希望有人能幫我。

在文章中,它聲明您需要使用@Transactional註解Spring bean,並使用@PersistenceContext註釋方法/域以提供事務支持並注入實體管理器。

是否有定義bean爲「Spring Bean」的東西?我有一個bean類上使用泛型實體實現CRUD操作:

@Transactional 
public class GenericCrudServiceBean implements GenericCrudService 
{ 
    @PersistenceContext(unitName="MyData") 
    private EntityManager em; 

    @Override 
    @PersistenceContext 
    public <T> T create(T t) 
    { 
     em.persist(t); 
     return t; 
    } 

    @Override 
    @PersistenceContext 
    public <T> void delete(T t) 
    { 
     t = em.merge(t); 
     em.remove(t); 
    } 
... 
... 
... 
    @Override 
    @PersistenceContext 
    public List<?> findWithNamedQuery(String queryName) 
    { 
     return em.createNamedQuery(queryName).getResultList(); 
    } 
} 

本來我只是有這個peristence背景註釋:

@PersistenceContext(unitName="MyData") 
private EntityManager em; 

,但有一個空的他們,當被調用findWithNamedQuery。然後我註釋了這些方法,但em仍然是空的(沒有注入?)。

我想知道這是否與我的bean沒有被識別爲「Spring」有關。

我已經做了配置,最好的,我可以按照文章中的方向,包括設置在我的context.xml文件如下:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns:tx="http://www.springframework.org/schema/tx" 
    tx:schemaLocation="http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"> 

    <bean id="entityManagerFactory" 
     class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
     <property name="persistenceUnitName" value="MyData" /> 
     <property name="dataSource" ref="dataSource" /> 
     <property name="loadTimeWeaver" 
      class="org.springframework.classloading.ReflectiveLoadTimeWeaver" /> 
     <property name="jpaVendorAdapter" ref="jpaAdapter" /> 
    </bean> 

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" 
     destroy-method="close"> 
     <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" /> 
     <property name="url" value="jdbc:oracle:thin:@localhost:1521:MySID" /> 
     <property name="username" value="user" /> 
     <property name="password" value="password" /> 
     <property name="initialSize" value="3" /> 
     <property name="maxActive" value="10" /> 
    </bean> 

    <bean id="jpaAdapter" 
     class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter"> 
     <property name="databasePlatform" 
      value="org.eclipse.persistence.platform.database.OraclePlatform" /> 
     <property name="showSql" value="true" /> 
    </bean> 

    <bean 
     class="org.springframework.ormmjpa.support.PersistenceAnnotationBeanPostProcessor" /> 
    <tx:annotation-driven /> 
</beans> 

我猜這屬於在context.xml文件,因爲文章從來沒有具體說過哪個文件是「應用程序上下文」文件。如果這是錯誤的,請讓我知道。

+2

與其閱讀關於如何在某些網站上做這些東西,你是否閱讀過Spring文檔? http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/orm.html#orm-jpa – skaffman 2010-06-09 21:00:11

+0

感謝您的鏈接。我實際上已經發現/閱讀了Spring文檔的一部分,但是它沒有提供任何關於我的配置可能出錯的信息。我對搜索「Spring bean」的搜索過於籠統,搜索不到任何合理的結果。 – sdoca 2010-06-09 22:20:01

+0

您正在使用哪種JPA實現? Spring不是JPA容器,但它與一個(例如Hibernate)集成。 – skaffman 2010-06-10 07:15:04

回答

0

爲了一類是一個Spring bean它必須是:

  • 要麼映射爲<bean id=".." class="..">@Component@Service,或類似的刻板印象註釋註解
  • 由你實例化。如果你想彈簧連接你的依賴關係,你必須讓它實例化你的類。因此,沒有new GenericCrudServiceBean()(也有「招數」使用new操作時啓用依賴注入甚至,但他們是在特殊情況下)

爲了不需要實例在前面你的類,你必須把東西」 「你的控制器和服務。對於網頁的框架,這將是一個Servlet,或添加到servlet,它通過彈簧 的ApplicationContext處理您的班級 - 在Spring MVCDispatcherServlet使用 - 在JSF定製的春季ELResolver用於

根據您的框架,尋找「X春天融合」。

對於你的情況 - 門戶組件 - 春天有Portlet MVC

+0

因此,如果我將@Service添加到我的班級,我已經達到了第一個要求。考慮到在Liferay/Tomcat上部署的Portlet中使用GenericCrudServiceBean,我該如何去解決第二個問題? Spring何時/將如何實例化它? – sdoca 2010-06-09 22:02:16

+0

你可以坐在前面攔截請求。例如調度程序servlet。閱讀文檔的相關部分。 – Bozho 2010-06-10 11:36:27

+0

感謝您的建議。我搜索了使用Spring和portlet的任何引用,因爲這是我正在使用的框架。它似乎不被支持。相反,@sdoca與 – sdoca 2010-06-16 20:30:43

0

在文章中它指出您需要,以提供交易支持標註一個Spring Bean與@Transactional與@PersistenceContext方法/字段和注入一個實體經理。

這是正確的,你不應該在你的方法添加@PersistenceContext,僅在private EntityManager em屬性。

是否有定義bean爲「Spring Bean」的東西?

這是一個由Spring容器管理的bean(即Spring管理其生命週期,將它與其他Spring bean連接起來等)。這意味着你在某個時候創建​​了一個Spring容器。

我猜想這些屬於context.xml文件,因爲文章從未明確地說過哪個文件是「應用程序上下文」文件。如果這是錯誤的,請讓我知道。

這屬於一個應用程序上下文文件,它只是一個XML文件,只要您告訴Spring容器加載它,名稱並不重要。而實際上,這是一個很大的問題:你如何運行你的代碼

這篇文章運行了一個測試用例,它擴展了Spring類,提供了Spring支持(我的意思是它將爲您創建Spring容器)並允許告訴Spring加載哪個應用程序上下文文件(在這種情況下,my-spring-config.xml)通過提供getConfigLocations方法:

package org.bookguru; 

import org.springframework.test.jpa.AbstractJpaTests; 

public class BookInventorySystemTest extends AbstractJpaTests { 

    private BookInventorySystem bookInventorySystem; 

    public void setBookInventorySystem(
     BookInventorySystem bookInventorySystem) { 
     this.bookInventorySystem = bookInventorySystem; 
    } 

    protected String[] getConfigLocations() { 
     return new String[] {"/my/path/my-spring-config.xml"}; 
    } 
} 

那麼,你怎麼跑你的代碼?

+0

我的代碼作爲Liferay/Tomcat中的portlet運行。這是因爲我們正在使用Liferay的Tomcat包(而不是部署到JEE容器),我正在使用Spring作爲JPA提供注入em和事務管理。 – sdoca 2010-06-09 21:57:36

+0

如果我有一個擴展Spring類的類(哪一個?)然後創建Spring容器,並且該類使用了GenericCrudServiceBean,這是否也會滿足Bozho的第二個需求?會很高興用一塊石頭殺死兩隻鳥... – sdoca 2010-06-09 22:06:38

+0

@sdoca我沒有足夠的關於portlet和liferay的知識來回答這個問題。 – 2010-06-09 22:25:01

0

值得一提的從Spring documentation

@EnableTransactionManagement以下,只查找@Transactional在他們中的定義相同的應用程序上下文豆,這意味着,如果你把註釋驅動的配置在WebApplicationContext對於DispatcherServlet,它只檢查控制器中的@Transactional bean,而不檢查您的服務。有關更多信息,請參見第17.2節「DispatcherServlet」。

這意味着當您使用portlet時,您必須在portlet上下文中啓用註釋驅動的事務。這可能是你的問題。

今天就打我了 - 我有一個多portlet應用程序,並希望設置應用程序上下文中的所有數據庫bean。這很好,並在我的所有測試中工作。

但是,當部署到portlet容器時,我的portlet特定的bean都沒有意識到該事務 - 原因是因爲缺少我的portletcontext。一旦我閱讀手冊,我就會清楚地看到......