2011-10-07 61 views
0

我嘗試開發一個簡單的Web應用程序,但爲了排除Web前端中所有錯誤的可能性,我編寫了一個從命令提示符執行的類。嘗試通過休眠訪問數據庫後出現NullPointerException

package org.vadim.testmvc; 

import org.vadim.testmvc.model.*; 
import org.vadim.testmvc.service.*; 
public class TestMain { 
    public static void main(String[] args){ 
     Strings s = new Strings(); 
     TestService ts = new TestService(); 
     s.setText("StrText"); 
     ts.addStrings(s); 
     System.out.println(ts.listStrings()); 
    } 
} 

TestService.java(不導入語句,但可以肯定他們是在原有上市至今):

package org.vadim.testmvc.service; 

@Service 
public class TestService implements TestServiceInterface { 

    //@Autowired 
    TestDAO testdao = new TestDAO(); 

    @Transactional 
    public List<Strings> listStrings(){ 
     return testdao.listStrings(); 
    } 

    @Transactional 
    public void addStrings(Strings strings){ 
     testdao.addStrings(strings); 
    } 
} 

TestDAO.java:

package org.vadim.testmvc.dao; 

@Transactional 
@Repository 
public class TestDAO implements TestDAOInterface { 

    @Autowired 
    private SessionFactory sessionFactory; 

    public void addStrings(Strings strings){ 
     sessionFactory.getCurrentSession().save(strings); 
    } 

    @SuppressWarnings("unchecked") 
    public List<Strings> listStrings(){ 
     return sessionFactory.getCurrentSession().createQuery("from Strings").list(); 
    } 
} 

實體類:

package org.vadim.testmvc.model; 

@Entity 
@Table(name="STRINGS") 
public class Strings { 

    @Id 
    @Column(name="ID") 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    private Integer id; 

    @Column(name="TEXT") 
    private String text; 

    public void setId(Integer id){ 
     this.id=id; 
    } 

    public Integer getId(){ 
     return id; 
    } 

    public String getText(){ 
     return text; 
    } 

    public void setText(String text){ 
     this.text=text; 
    } 
} 

hibernate.cfg.xm升:

<?xml version='1.0' encoding='utf-8'?> 
<!DOCTYPE hibernate-configuration PUBLIC 
    "-//Hibernate/Hibernate Configuration DTD//EN" 
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> 
<hibernate-configuration> 
<session-factory> 
<mapping class="org.vadim.testmvc.model.Strings"/> 
</session-factory> 
</hibernate-configuration> 

根的context.xml

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

<context:annotation-config/> 
<context:component-scan base-package="org.vadim.testmvc.dao"/> 
<context:component-scan base-package="org.vadim.testmvc.service"/> 
<import resource="data.xml"/> 
</beans> 

data.xml中

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

<tx:annotation-driven transaction-manager="transactionManager"/> 

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 
<property name="sessionFactory" ref="sessionFactory"/> 
</bean> 

<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> 
<property name="basename" value="classpath:messages"/> 
<property name="defaultEncoding" value="UTF-8"/> 
</bean> 

    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" p:location="/WEB-INF/jdbc.properties"/> 

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.databaseurl}" p:username="${jdbc.username}" p:password="${jdbc.password}"/> 

    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource"/> 
    <property name="configLocation"> 
    <value>classpath:hibernate.cfg.xml</value> 
    </property> 
    <property name="configurationClass"> 
    <value>org.hibernate.cfg.AnnotationConfiguration</value> 
    </property> 
    <property name="hibernateProperties"> 
    <props> 
    <prop key="hibernate.show_sql">true</prop> 
    <prop key="hibernate.dialect">${jdbc.dialect}</prop> 
    <prop key="hibernate.connection.charSet">UTF-8</prop> 
    </props> 
    </property> 
    </bean> 
    </beans> 

這是例外遭遇後堆棧跟蹤:

Exception in thread "main" java.lang.NullPointerException 
    at org.vadim.testmvc.dao.TestDAO.listStrings(TestDAO.java:23) 
    at org.vadim.testmvc.service.TestService.listStrings(TestService.java:18) 
    at org.vadim.testmvc.TestMain.main(TestMain.java:11) 

相同如果我嘗試執行TestDAO.addStrings,則會發生(Strings strings)方法,也就是說問題不在listStrings()的返回結果中,而是在訪問數據庫中。我試圖從mysql命令提示符添加一些條目,使其不是空的。我成功地做到了這一點,但這並沒有影響程序的行爲。

這裏是我所得到的只是,如果申報TestService testservice;與@Autowire註釋

ERROR: org.springframework.web.context.ContextLoader - Context initialization failed 
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.vadim.testmvc.dao.TestDAO org.vadim.testmvc.service.TestService.testdao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [org.vadim.testmvc.dao.TestDAO] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1074) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:580) 
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895) 
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425) 
    at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:276) 
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:197) 
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47) 
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4723) 
    at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5226) 
    at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5221) 
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:166) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) 
    at java.lang.Thread.run(Thread.java:722) 
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.vadim.testmvc.dao.TestDAO org.vadim.testmvc.service.TestService.testdao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [org.vadim.testmvc.dao.TestDAO] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:502) 
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84) 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:282) 
    ... 21 more 
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [org.vadim.testmvc.dao.TestDAO] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:920) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:789) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:703) 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:474) 
    ... 23 more 
+0

確保一切都剛剛展開。異常意味着dao不被識別爲spring bean,但是它應該,因爲它被註釋了@Repository – Bozho

回答

0

我想你會發現它是@Bozho和@smp7d答案的組合。您需要加載彈簧配置,確保您已經爲該配置中的TestDao定義了一個bean,並取消註釋@Autowired。

+0

也許這是一種愚蠢的問題,但在加載彈簧配置時,你是什麼意思?我應該添加到root-context.xml,如''? –

1

我不知道你爲什麼註釋掉@Autowired,但它會導致你的問題:

//@Autowired 
TestDAO testdao = new TestDAO(); 

當您手動創建TestDAO Spring不能注入TestDAO.sessionFactory,這是null。取消註釋這個註釋,並刪除= new TestDAO()

@Autowired 
private TestDAO testdao; 
+0

我剛剛編輯了我的帖子以顯示結果。我最初試圖做到這一點,並且改變了我提出的觀點。 –

0

在main方法,你是不是使彈簧加載的配置...這樣的類成員將不會被自動裝配。

加載您的配置,從上下文/ bean工廠獲取您的TestService bean,並確保您自動調試TestDao。

0

請嘗試添加到道;

public HibernateTemplate hibernateTemplate; public Session session = null;

@Autowired 
public void setSessionFactory(SessionFactory sessionFactory) { 
    hibernateTemplate = new HibernateTemplate(sessionFactory); 
} 
+0

這不是問題,他不使用模板 – Bozho

+0

這是正確的,這並沒有改變。 –

+0

是的,你是正確的忽視,你可以嘗試 sessionFactory.openSession(),而不是sessionFactory.getCurrentSession() –

0

老子的事情是亙古不變的獲取當前會話 你可以使用sessionFactory.openSession()代替sessionFactory.getCurrentSession()