2012-02-16 77 views
1

美好的一天,EntityManager始终为NULL使用SpringFramework

我一直在研究Maven + Spring + Hibernate项目。实际上,这只是一个测试项目,只是为了熟悉Spring如何使用Hibernate(+ Maven)。我已经设置并准备了必要的依赖关系。即Spring的appcontext.xml,Hibernate的persistence.xml,JPA/Persistence/Hibernate的实体和DAO对象。

在调试期间,观察到EntityManager总是null。我不知道是什么导致了这一点,因为我已经做了FF:

  1. 自动装配它在我的控制器上
  2. 宣布它作为一个bean我applicationContext.xml
  3. 我的注释DAO对象@Repository
  4. 定义entityManagerFactorytransactionManagervendorAdapter如豆类我applicationContext.xml

我一直在调试,并试图解决方法一整天。不幸的是,我还没有解决这个问题。希望有人可以在这个问题上提出一些看法。

下面是我的项目的代码和配置:

< --- persistence.xml中--->

<persistence xmlns="http://java.sun.com/xml/ns/persistence" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence 
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" 
version="1.0"> 
    <persistence-unit name="msh" transaction-type="RESOURCE_LOCAL"> 
     <provider>org.hibernate.ejb.HibernatePersistence</provider> 
     <class>com.msh.TblFileinfo</class> 
    </persistence-unit> 
</persistence> 

< --- applicationContext.xml的--->

<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:context="http://www.springframework.org/schema/context" 
     xmlns:tx="http://www.springframework.org/schema/tx" 
     xmlns:lang="http://www.springframework.org/schema/lang" 
     xsi:schemaLocation="http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
      http://www.springframework.org/schema/tx 
      http://www.springframework.org/schema/tx/spring-tx-3.0.xsd 
      http://www.springframework.org/schema/context 
      http://www.springframework.org/schema/context/spring-context-3.0.xsd 
      http://www.springframework.org/schema/lang 
      http://www.springframework.org/schema/lang/spring-lang-3.0.xsd 
      http://www.springframework.org/schema/security"> 

    <!-- need to create database.properties file --> 
    <context:property-placeholder location="classpath:database.properties"/> 

    <context:component-scan base-package="com.msh"/> 

    <!-- tell Spring that it should act on any @PersistenceContext and @Transactional annotations found in bean classes --> 
    <!-- <tx:annotation-driven/> --> 
    <tx:annotation-driven transaction-manager="transactionManager"/> 

    <bean class="com.msh.TblFileinfoHome" /> 
    <bean class="com.msh.TblFileinfo" /> 

    <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" /> 

    <bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
     <!-- <property name="databasePlatform" value="${platform}" /> --> 
     <property name="showSql" value="${database.showSql}" /> 
     <property name="generateDdl" value="${database.generateDdl}" /> 
    </bean> 

    <bean id="entityManagerFactory" class="org.org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
     <property name="persistenceUnitName" value="msh" /> 
     <property name="dataSource" ref="dataSource" /> 
     <!-- <property name="loadTimeWeaver" class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" /> --> 
     <property name="jpaVendorAdapter" ref="jpaVendorAdapter" /> 
    </bean> 

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
     <property name="entityManagerFactory" ref="entityManagerFactory" /> 
    </bean> 

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
     <property name="driverClassName" value="${database.driverClassName}" /> 
     <property name="url" value="${database.url}" /> 
     <property name="username" value="${database.username}" /> 
     <property name="password" value="${database.password}" /> 
    </bean> 
</beans> 

< ---主要java代码--->

package com.msh; 

public class MavenSpringHibernate { 

    /** 
    * @param args 
    */ 

    public static void main(String[] args) { 
     // TODO Auto-generated method stub 
     Sample s = new Sample(); 
     s.persist(); 
    } 
} 

< --- --- DAO>

package com.msh; 

import javax.ejb.Stateless; 
import javax.persistence.EntityManagerFactory; 
import javax.persistence.EntityManager; 
import javax.persistence.Persistence; 
import javax.persistence.PersistenceUnit; 
import javax.persistence.PersistenceContext; 
import org.springframework.stereotype.Repository; 
import org.springframework.transaction.annotation.Transactional; 
import org.apache.commons.logging.Log; 
import org.apache.commons.logging.LogFactory; 

/** 
* Home object for domain model class TblFileinfo. 
* @see com.trendmicro.grid.mshPackage.TblFileinfo 
* @author Hibernate Tools 
*/ 

/** 
@Stateless 
@Repository 
@Transactional 
*/ 

@Repository 
public class TblFileinfoHome { 

    private static final Log log = LogFactory.getLog(TblFileinfoHome.class); 

    @PersistenceContext(unitName="msh") 
    private EntityManager entityManager; 

    @Transactional 
    public void persist(TblFileinfo transientInstance) { 
     log.debug("persisting TblFileinfo instance"); 
     try { 
      entityManager.persist(transientInstance); 
      log.debug("persist successful"); 
     } 
     catch (RuntimeException re) { 
      log.error("persist failed", re); 
      throw re; 
     } 
    } 

    @Transactional 
    public void remove(TblFileinfo persistentInstance) { 
     log.debug("removing TblFileinfo instance"); 
     try { 
      entityManager.remove(persistentInstance); 
      log.debug("remove successful"); 
     } 
     catch (RuntimeException re) { 
      log.error("remove failed", re); 
      throw re; 
     } 
    } 

    @Transactional 
    public TblFileinfo merge(TblFileinfo detachedInstance) { 
     log.debug("merging TblFileinfo instance"); 
     try { 
      TblFileinfo result = entityManager.merge(detachedInstance); 
      log.debug("merge successful"); 
      return result; 
     } 
     catch (RuntimeException re) { 
      log.error("merge failed", re); 
      throw re; 
     } 
    } 

    @Transactional 
    public TblFileinfo findById(Long id) { 
     log.debug("getting TblFileinfo instance with id: " + id); 
     try { 
      TblFileinfo instance = entityManager.find(TblFileinfo.class, id); 
      log.debug("get successful"); 
      return instance; 
     } 
     catch (RuntimeException re) { 
      log.error("get failed", re); 
      throw re; 
     } 
    } 
} 

--- ---实体

package com.msh; 


import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 

import static javax.persistence.GenerationType.IDENTITY; 
import javax.persistence.Id; 
import javax.persistence.Table; 

/** 
* TblFileinfo generated by hbm2java 
*/ 
@Entity 
@Table(name="tbl_fileinfo" 
    ,catalog="behavior" 
) 
public class TblFileinfo implements java.io.Serializable { 


    private Long fileId; 
    private String filename; 
    private String filetype; 

    public TblFileinfo() { 
    } 

    public TblFileinfo(String filename, String filetype) { 
     this.filename = filename; 
     this.filetype = filetype; 
    } 

    @Id @GeneratedValue(strategy=GenerationType.AUTO) 


    @Column(name="file_id", unique=true, nullable=false) 
    public Long getFileId() { 
     return this.fileId; 
    } 

    public void setFileId(Long fileId) { 
     this.fileId = fileId; 
    } 


    @Column(name="filename", length=200) 
    public String getFilename() { 
     return this.filename; 
    } 

    public void setFilename(String filename) { 
     this.filename = filename; 
    } 


    @Column(name="filetype", length=50) 
    public String getFiletype() { 
     return this.filetype; 
    } 

    public void setFiletype(String filetype) { 
     this.filetype = filetype; 
    } 
} 

< --- Sample类控制器--->

package com.msh; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.transaction.annotation.Transactional; 
import com.trendmicro.grid.msh.TblFileinfo; 
import com.trendmicro.grid.msh.TblFileinfoHome; 


@Transactional 
public class Sample { 
    @Autowired 
    private TblFileinfo tinfo; 
    private TblFileinfoHome tinfoh; 

    public Sample() 
    { 
     tinfo = new TblFileinfo("c:/jayson/murillo/pryde.exe", "uv_win32"); 
     tinfoh = new TblFileinfoHome(); 
    } 

    public void persist() 
    { 
     tinfoh.persist(tinfo); 
    } 
} 

再次,希望有人可以提供这方面的反馈意见。提前致谢!

回答

2

你甚至没有开始春!

Sample s = new Sample(); 

Sample是一个Spring bean。您必须先启动应用程序上下文并从那里获取bean。见@ nico_ekito的回答是:

public static void main(String[] args) { 
    ApplicationContext context = 
     new ClassPathXmlApplicationContext("classpath:/applicationContext.xml"); 
    Sample s = context.getBean(Sample.class); 
    s.persist(); 
} 

一旦你开始上下文(这可能会与一些错误结果),更正如下:

  • 删除此:

    tinfoh = new TblFileinfoHome(); 
    

    注释字段附:

    @Autowired 
    private TblFileinfoHome tinfoh; 
    
  • 你不应该自动装配实体类:

    @Autowired    //remove this annotation 
    private TblFileinfo tinfo; 
    
+0

感谢。但是,“Sample s = context.getBean(Sample.class);”不允许...我的意思是我有一些错误 – jaysonpryde 2012-02-16 11:47:49

+0

@jaysonpryde:什么错误?您使用的是哪个版本的Spring和Java?编译错误或运行时异常? – 2012-02-16 12:00:48

+0

@ Tomasz - 由于我没有声明Sample class为applicationContext.xml中的bean,我想我不能这样做......错误是这样的:“类型BeanFactory中的方法getBean(String)不适用为参数(类)“ – jaysonpryde 2012-02-16 12:04:02

2

你不加载Spring上下文中的主类:

public class MavenSpringHibernate { 

    /** 
    * @param args 
    */ 

    public static void main(String[] args) { 

     ApplicationContext context = 
       new ClassPathXmlApplicationContext(new String[] {"classpath:/PATH/TO/applicationContext.xml"}); 

     Sample s = context.getBean(Sample.class); 
     s.persist(); 
    } 
} 
+0

+1,我一直非常关注自动装配问题,我甚至没有意识到Spring应用程序上下文根本没有启动:-)。 – 2012-02-16 10:47:50