user3116769
user3116769

Reputation: 59

Spring : Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException

First I want to start off saying that I'm a bit new to Spring so the conceptual aspect of it is a bit unclear, and thusly preventing me from understanding the implementation. I'm trying to integrate hibernate and spring together, but I continually get this error.

    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

Here's my BankDAO class

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);
    }
}

Façade class

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>

Any help is appreciated thank you.

Upvotes: 1

Views: 10197

Answers (1)

Arpit Aggarwal
Arpit Aggarwal

Reputation: 29316

Error log clearly telling that it is not finding setter for bankDAO

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?

To fix it, create property bankDAO along with setter/getter as follows:

    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;
        }
    }

Also check bean named "facade", as from error logs it seems it should be:

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

not

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

Upvotes: 2

Related Questions