2010-06-09 43 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。一旦我阅读手册,我就会清楚地看到......