2017-03-01 256 views
-2

我有基於Spring的應用程序,我需要讓Hibernate工作。所以我得到了啓發本教程:A Guide to Hibernate with Spring 4和我創建的java類(我想配置Hibernate XML-以內):使用JPA配置創建Spring bean的空指針異常

package com.mycompany.cmms.web.config; 



import java.util.Properties; 

import javax.persistence.EntityManagerFactory; 
import javax.sql.DataSource; 

import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; 
import org.springframework.jdbc.datasource.DriverManagerDataSource; 
import org.springframework.orm.jpa.JpaTransactionManager; 
import org.springframework.orm.jpa.JpaVendorAdapter; 
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; 
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; 
import org.springframework.transaction.PlatformTransactionManager; 
import org.springframework.transaction.annotation.EnableTransactionManagement; 

@Configuration 
@EnableTransactionManagement 
public class PersistanceJPAConfig { 


    @Bean 
    public EntityManagerFactory entityManagerFactory() { 
     LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); 
     em.setDataSource(dataSource()); 
     em.setPackagesToScan(new String[] { "com.vsb.cmms.domain" }); 

     JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); 
     em.setJpaVendorAdapter(vendorAdapter); 
     em.setJpaProperties(additionalProperties()); 

     return em.getObject(); 
    } 

    @Bean 
    public DataSource dataSource(){ 
     DriverManagerDataSource dataSource = new DriverManagerDataSource(); 
     dataSource.setDriverClassName("org.postgresql.Driver"); 
     dataSource.setUrl("jdbc:postgresql://localhost:5432/cmms"); 
     dataSource.setUsername("postgres"); 
     dataSource.setPassword("xxx"); 
     return dataSource; 
    } 



    @Bean 
    public PlatformTransactionManager transactionManager(EntityManagerFactory emf){ 
     JpaTransactionManager transactionManager = new JpaTransactionManager(); 
     transactionManager.setEntityManagerFactory(emf); 

     return transactionManager; 
    } 

    @Bean 
    public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){ 
     return new PersistenceExceptionTranslationPostProcessor(); 
    } 

    Properties additionalProperties() { 
     Properties properties = new Properties(); 
     properties.setProperty("hibernate.hbm2ddl.auto", "create-drop"); 
     properties.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect"); 
     properties.setProperty("hibernate.query.factory_class", "org.hibernate.hql.internal.classic.ClassicQueryTranslatorFactory"); 
     return properties; 
    } 
} 

但是當我建立並啓動我的應用程序,我得到這個錯誤:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager' defined in com.vsb.cmms.web.config.PersistanceJPAConfig: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: 'entityManagerFactory' or 'persistenceUnitName' is required 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1583) 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545) 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) 
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) 
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) 
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) 
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) 
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:751) 
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:861) 
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541) 
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:444) 
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:326) 
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107) 
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4717) 
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5179) 
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) 
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1404) 
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1394) 
at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
at java.lang.Thread.run(Thread.java:745) 
Caused by: java.lang.IllegalArgumentException: 'entityManagerFactory' or 'persistenceUnitName' is required 
at org.springframework.orm.jpa.JpaTransactionManager.afterPropertiesSet(JpaTransactionManager.java:304) 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1642) 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1579) 
... 21 more 

錯誤是說需要'entityManagerFactory'或'persistenceUnitName'。但實體管理器工廠應通過entityManagerFactory()提供。 當我debbuged硫豆我注意到em.getObject()返回null,並可能導致錯誤,雖然我不知道爲什麼會發生這種情況。我正在使用Spring 4和Hibernate 5.2.3.Final。

+2

「'entityManagerFactory'或'persistenceUnitName'是必需的」。那不清楚的是什麼?你在哪裏看到一個NullPointerException? – Tunaki

+0

我注意到,但這個錯誤是由entityManagerFactory(),因爲它返回null導致我的問題是:爲什麼以及如何解決它。 –

+0

你可以檢查用@Entity註解的類是否存在於這個包中com.vsb.cmms.domain – pkoli

回答

0

entityManagerFactory()方法確實不應該叫#getObject()而是你應該寫:

@Bean 
public LocalContainerEntityManagerFactoryBean entityManagerFactory() { 
    LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); 
    em.setDataSource(dataSource()); 
    em.setPackagesToScan(new String[] { "com.vsb.cmms.domain" }); 

    JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); 
    em.setJpaVendorAdapter(vendorAdapter); 
    em.setJpaProperties(additionalProperties()); 

    // just return the bean here 
    return em; 
} 

春處理該工廠bean自動給你EntityManagerFactory實例。

+0

如果我改變它的錯誤消失但EntityManager或EntityManagerFacotry在我的DAO類中爲null。 –

+0

你是用'@ PersistenceContext'注入它嗎? – Naros

0

就在互聯網的深處發現... 如果你想使XML少Hibernate的配置有機會輕鬆地控制會話(會話應用程序或會話交易),那麼你可能想看看this

請注意,代碼,因爲它是完美的,直到休眠5.2版本