Search code examples
springtransactionsannotationsjdo

Bean property 'persistenceManagerFactory' is not writable or has an invalid setter method


I am running maven jdo project. And i want to use annotational transactions so i have set my dispatcher according to this but i am getting this error following error.

org.springframework.beans.factory.BeanCreationException: Error creating
bean with name 'myController': Injection of autowired dependencies 
failed; nested exception is 
org.springframework.beans.factory.BeanCreationException: Could not
autowire field: private com.titas.dao.UserDAO 
com.titas.controller.MyController.userDAO; nested exception is 
org.springframework.beans.factory.BeanCreationException: Error creating
bean with name 'userDAO' defined in ServletContext resource [/WEB-
INF/dispatcher-servlet.xml]: Error setting property values; nested 
exception is org.springframework.beans.NotWritablePropertyException: 
Invalid property 'persistenceManagerFactory' of bean class 
[com.titas.dao.UserDAOImpl]: Bean property 'persistenceManagerFactory' 
is not writable or has an invalid setter method. Does the parameter type 
of the setter match the return type of the getter?

My dispatcher.xml is:

<!-- declare mvc to be annotation driven -->
<mvc:annotation-driven/>
<!-- provide Your Base package to scan annotations for components -->
<context:component-scan base-package="com.titas.controller"></context:component-scan>
<mvc:resources location="/resources/" mapping="/resources/**"/>
 <!-- enable the configuration of transactional behavior based on annotations-->
<tx:annotation-driven transaction-manager="txManager"/>


<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>

<!--
Most controllers will use the ControllerClassNameHandlerMapping above, but
for the index controller we are using ParameterizableViewController, so we must
define an explicit mapping for it.
-->
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <props>
            <prop key="index">indexController</prop>
        </props>
    </property>
</bean>

<bean id="viewResolver"
      class="org.springframework.web.servlet.view.InternalResourceViewResolver"
      p:prefix="/WEB-INF/jsp/"
      p:suffix=".jsp" />

<!--The index controller.-->
<bean name="indexController"
      class="org.springframework.web.servlet.mvc.ParameterizableViewController"
      p:viewName="index" />

<bean id="dataSource"
  class="org.springframework.jdbc.datasource.DriverManagerDataSource"
    p:driverClassName="com.mysql.jdbc.Driver"
    p:url="jdbc:mysql://localhost:3306/login"
    p:username="root"
    p:password="" />

<!-- PMF Bean -->
<bean id="myPmf" class="org.springframework.orm.jdo.LocalPersistenceManagerFactoryBean">
    <property name="jdoPropertyMap">
            <props>
                <prop key="javax.jdo.PersistenceManagerFactoryClass">org.datanucleus.api.jdo.JDOPersistenceManagerFactory</prop>
                <prop key="javax.jdo.option.ConnectionDriverName">com.mysql.jdbc.Driver</prop>
                <prop key="javax.jdo.option.ConnectionURL">jdbc:mysql://localhost:3306/login</prop>
                <prop key="javax.jdo.option.ConnectionUserName">root</prop>
                <prop key="javax.jdo.option.NontransactionalRead">true</prop>
                <prop key="javax.jdo.option.RetainValues">false</prop>
                <prop key="javax.jdo.option.DetachAllOnCommit">true</prop>
                <prop key="javax.jdo.option.Multithreaded">true</prop>
                <prop key="datanucleus.appengine.ignorableMetaDataBehavior">NONE</prop>
            </props>
    </property>
</bean>

<bean id="pmfProxy" class="org.springframework.orm.jdo.TransactionAwarePersistenceManagerFactoryProxy">
<property name="targetPersistenceManagerFactory" ref="myPmf"/>
<property name="allowCreate" value="false"/>
</bean>   


<bean id="txManager" class="org.springframework.orm.jdo.JdoTransactionManager">
    <property name="dataSource" ref="dataSource"/>
    <property name="persistenceManagerFactory" ref="pmfProxy"/>
</bean>

<bean id="userDAO" class="com.titas.dao.UserDAOImpl" >
    <property name="persistenceManagerFactory" ref="pmfProxy"/>
</bean>

UserDAOImpl.java

@Repository

public class UserDAOImpl implements UserDAO{ static Logger log = Logger.getLogger(UserDAOImpl.class.getName());

@Autowired
@Qualifier("dataSource")
private DataSource dataSource; 
@Autowired
@Qualifier("myPmf")
private PersistenceManagerFactory persistenceManagerFactory;

HttpServletRequest request;


@Override
@Transactional
public User getUser(String user_name, String user_password) {
    PersistenceManager pm = this.persistenceManagerFactory.getPersistenceManager();
    try {
        User user=new User();
        pm.makePersistent(user);
        Query query = pm.newQuery(User.class, "this.userName == userNameParam && this.userPassword==userPasswordParam");
        query.setFilter("this.userName == userNameParam && this.userPassword==userPasswordParam");
        query.declareParameters("String lastNameParam, String userPasswordParam");
        log.info("hereeee 5");
        log.info("hereeee again 5");
        user = (User)query.execute(user_name,user_password);
        log.info("hereeee 6");
        log.info("hereeee again 6");
        log.info(user.getUserEmail()+"..........."+user.getUserProfileName());
        return user;
    }
    finally {
        pm.close();
    } 
 }

MyController.java

@Controller
//@RequestMapping(value = "/test")
public class MyController{

  static Logger log = Logger.getLogger(MyController.class.getName());
  @Autowired
  private UserDAO userDAO;
  List<User> allUser = new ArrayList<User>();

May i know where i need to change. Thanks in advance.


Solution

  • Your bean definition is:

    <bean id="userDAO" class="com.titas.dao.UserDAOImpl" >
        <property name="persistenceManagerFactory" ref="pmfProxy"/>
    </bean>
    

    In your UserDaoImpl you havent defined a method called setPersistenceManagerFactory which Spring is complaining about.

    By above bean definition, Spring is going to inject factory object within user dao via setter method which is not present and hence you see exception.

    So instead of:

    @Qualifier("myPmf")
    

    You should use bean name for proxy factory object (although i don't see problem using myPmf, it's just what you tries to inject property using <property name="persistenceManagerFactory" ref="pmfProxy"/> in userDao bean and hence this suggestion and you could ignore this) like:

    @Qualifier("pmfProxy")
    

    And remove the line which tries to inject property when you say autowired:

    <bean id="userDAO" class="com.titas.dao.UserDAOImpl" />
    

    from your bean definition for userDAO as Spring is going to inject it for you.

    If you want to manually specify the dependency and inject it via setter then you would need to define setter method like:

     .. setPersistenceManagerFactory(..) {
           ....
     }