Spring:设置属性值时出错;嵌套异常是org.springframework.beans.NotWritablePropertyException

时间:2017-01-08 10:25:55

标签: java spring hibernate spring-mvc dependency-injection

首先,我想开始说我对Spring有点新,所以它的概念方面有点不清楚,因此阻止我理解实现。我正在尝试将hibernate和spring集成在一起,但我不断得到这个错误。

    Error creating bean with name 'facade' defined in class path resource [beans.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'bankDAO' of bean class [data.Facade]: Bean property 'bankDAO' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
org.springframework.beans.factory.BeanCreationException
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1396)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1118)
    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:294)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:607)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:925)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:472)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
    at JUnitTest.HibernateTest.setup(HibernateTest.java:40)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:53)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:123)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:104)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164)
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110)
    at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:175)
    at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:107)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:68)
Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'bankDAO' of bean class [data.Facade]: Bean property 'bankDAO' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
    at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:1064)
    at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:924)
    ... 37 more

这是我的BankDAO课程

package data;

import org.hibernate.SessionFactory;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import beans.Bank;

public class BankDAO {
    private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Bank get(int id) {
        return (Bank) sessionFactory.getCurrentSession().get(Bank.class, id);
    }

    @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Bank load(int id) {
        return (Bank) sessionFactory.getCurrentSession().load(Bank.class, id);
    }
}

外墙课

package data;


import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import beans.*;
import java.util.List;

public class Facade {

    private SessionFactory sf = new Configuration().configure().buildSessionFactory();
    private static ApplicationContext contxt;

    public static void getContext() {
        contxt = new ClassPathXmlApplicationContext("beans.xml");
    }


    public void createAccount(AccountDAO account){
        contxt.getBean(AccountDAO.class).insert(account);
        System.out.println("Event was inserted");       
    }

        public List<Account> getAllAccounts(){
            return contxt.getBean(AccountDAO.class).getAll();
        }

    }

的beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<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:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">

    <!-- Use @Transactional instead of <tx:advice> -->
    <tx:annotation-driven />

    <!-- DataSource bean -->
    <bean name="ds" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="oracle.jdbc.OracleDriver" />
        <property name="username" value="root" />
        <property name="password" value="" />
        <property name="url"      value="localhost" />
    </bean>


    <!-- SessionFactory -->
    <bean name="sf"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="ds" />
        <property name="packagesToScan" value="beans" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.connection.pool_size">20</prop>
                <prop key="hibernate.dialect"> org.hibernate.dialect.Oracle10gDialect </prop>
                <prop key="show_sql">true</prop>
            </props>
        </property>
    </bean>


    <!-- Transaction Manager -->
    <bean name="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sf" />
    </bean>


    <!-- DAO beans -->
    <bean name="bankDAO"      class="data.BankDAO">      <property name="sessionFactory" ref="sf" /> </bean>
    <bean name="accountDAO"         class="data.AccountDAO">         <property name="sessionFactory" ref="sf" /> </bean>
     </bean>


    <!-- Facade bean -->
    <bean name="facade" class="dataTier.DataFacade">
        <property name="bankDAO" ref="bankDAO" />
                <property name="accountDAO" ref="accountDAO" /> 
    </bean>


</beans>

感谢您的任何帮助。

1 个答案:

答案 0 :(得分:2)

错误日志清楚地告诉它没有找到bankDAO

的setter
  

在类路径资源中定义名为'facade'的bean时出错   [beans.xml]:设置属性值时出错;嵌套异常是   org.springframework.beans.NotWritablePropertyException:无效   bean类的属性'bankDAO'[data.Facade]:Bean属性   'bankDAO'不可写或具有无效的setter方法。是吗?   setter的参数类型与getter的返回类型匹配?

要解决此问题,请按以下步骤创建属性bankDAOsetter/getter

    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import beans.*;
    import java.util.List;

    public class Facade {

        private SessionFactory sf = new Configuration().configure()
                .buildSessionFactory();
        private static ApplicationContext contxt;

        private BankDAO bankDAO;

        public static void getContext() {
            contxt = new ClassPathXmlApplicationContext("beans.xml");
        }

        public void createAccount(AccountDAO account) {
            contxt.getBean(AccountDAO.class).insert(account);
            System.out.println("Event was inserted");
        }

        public List<Account> getAllAccounts() {
            return contxt.getBean(AccountDAO.class).getAll();
        }

        public BankDAO getBankDAO() {
            return bankDAO;
        }

        public void setBankDAO(BankDAO bankDAO) {
            this.bankDAO = bankDAO;
        }
    }

同时检查名为“facade”的bean ,从错误日志看起来应该是:

<!-- Facade bean -->
<bean name="facade" class="dataTier.Facade">
    <property name="bankDAO" ref="bankDAO" />
    <property name="accountDAO" ref="accountDAO" /> 
</bean>

<!-- Facade bean -->
<bean name="facade" class="dataTier.DataFacade">
     <property name="bankDAO" ref="bankDAO" />
     <property name="accountDAO" ref="accountDAO" /> 
</bean>