Java – Error creating bean if have @Repository or a PersistenceExceptionTranslationPostProcessor bean

javaspring

I am a rookie in spring and I am learning spring using the book Spring Recipes: A problem solution approach by Gary Mak.

Anyway I had this problem while using
PersistenceExceptionTranslationPostProcessor.

Here is my applicationContext.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:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:jee="http://www.springframework.org/schema/jee"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
                           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">

  <context:property-placeholder location="jdbc.properties"/>

  <tx:annotation-driven proxy-target-class="true" />

  <bean id="dataSource"
        class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName"
                  value="${jdbc.driverClassName}" />       
      <property name="url"
                  value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
 <!-- <property name="configLocation" value="classpath:hibernate.cfg.xml" /> -->
 <property name="dataSource" ref="dataSource" />
 <property name="mappingResources">
   <list>
    <value>com/hibernateproj2/domain/Employee.hbm.xml</value>
   </list>
 </property> 
 <property name="hibernateProperties">
    <props>
        <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
        <prop key="hibernate.show_sql">true</prop>
        <prop key="hibernate.hbm2ddl.auto">update</prop>
    </props>
 </property>
</bean> 

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


<bean id="employeeDaoImpl" class="com.hibernateproj2.dao.EmployeeDaoImpl">
   <property name="sessionFactory" ref="sessionFactory" />
</bean>

<bean id="hibWorker" class="HibWorker" >
  <property name="employeeDaoImpl" ref="employeeDaoImpl" />
</bean>

<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

</beans>

……………….

@Repository
    public class EmployeeDaoImpl implements EmployeeDao{
           ...........
    }


    public class HibWorker implements Worker{
    .......................

     @Transactional
    public void doTrans(){
       ......................
       }
       ...............

    }

    ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

In this case i am getting the below error while loading the applicationContext.xml

ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext .xml");

   log4j:WARN No appenders could be found for logger (org.springframework.context.support.ClassPathXmlApplicationContext).
log4j:WARN Please initialize the log4j system properly.
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hibWorker' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert property value of type [$Proxy5 implementing com.hibernateproj2.dao.EmployeeDao,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] to required type [com.hibernateproj2.dao.EmployeeDaoImpl] for property 'employeeDaoImpl'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [$Proxy5 implementing com.hibernateproj2.dao.EmployeeDao,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] to required type [com.hibernateproj2.dao.EmployeeDaoImpl] for property 'employeeDaoImpl': no matching editors or conversion strategy found
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:480)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
 at java.security.AccessController.doPrivileged(Native Method)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
 at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
 at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:221)
 at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
 at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
 at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
 at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:429)
 at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:729)
 at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:381)
 at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
 at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
 at Main.main(Main.java:10)
Caused by: org.springframework.beans.TypeMismatchException: Failed to convert property value of type [$Proxy5 implementing com.hibernateproj2.dao.EmployeeDao,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] to required type [com.hibernateproj2.dao.EmployeeDaoImpl] for property 'employeeDaoImpl'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [$Proxy5 implementing com.hibernateproj2.dao.EmployeeDao,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] to required type [com.hibernateproj2.dao.EmployeeDaoImpl] for property 'employeeDaoImpl': no matching editors or conversion strategy found
 at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:391)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1288)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1249)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1010)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:472)
 ... 14 more
Caused by: java.lang.IllegalArgumentException: Cannot convert value of type [$Proxy5 implementing com.hibernateproj2.dao.EmployeeDao,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] to required type [com.hibernateproj2.dao.EmployeeDaoImpl] for property 'employeeDaoImpl': no matching editors or conversion strategy found
 at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:219)
 at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:138)
 at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:386)
 ... 18 more

but when i comment out @Repository annotation on EmployeeDaoImpl or if I comment out PersistenceExceptionTranslationPostProcessor bean declaration, then the applicationContext loads properly.

    <!-- <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />  -->

or

//@Repository
public class EmployeeDaoImpl implements EmployeeDao{
       ...........
}

I would like to know why this is happening. Could anyone please explain me this.

Best Answer

Type of HibWorker.employeeDaoImpl is EmployeeDaoImpl, therefore exception translation proxy of type HibernateDao can't be assigned to it.

Generally it's a bad practise to restrict implementation of dependencies this way, you should use interface (EmployeeDao) when declaring dependencies instead. If you follow that way, you also don't need proxy-target-class = "true" on <tx:annotation-driven>.

Alternative solution is to enable target class proxying for PersistenceExceptionTranslationPostProcessor.

See also:

Related Topic