I am new in Spring. I have tried a demo project with Spring MVC, Hibernate, Spring-tx and Spring ORM. There I am facing the error. My scenario is:
public interface DaoInterface{
public SessionFactory getSessionFactory();
public Session getSession();
}
Another class BaseDao:
public abstract class BaseDao implements DaoInterface{
@Autowired
private SessionFactory sessionFactory;
private Session session;
public SessionFactory getSessionFactory() {
return this.sessionFactory;
}
public Session getSession() {
this.session = sessionFactory.getCurrentSession();
return this.session;
}
public abstract User retriveUser(String email);
}
Another class UserDao:
@Component
public class UserDao extends BaseDao{
@Override
@Transactional
public User retriveUser(String email) {
System.out.println("In userDao : retriveUser");
//other code
}
}
Now from my service class, when I am going to get UserDao object using BaseDao, I got the error:
org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'userDao' is expected to be of type 'dao.BaseDao' but was actually of type 'com.sun.proxy.$Proxy94'
My service class code:
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
BaseDao userDao = context.getBean("userDao", BaseDao.class);
If I do the following, no error comes.
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
DaoInterface userDao = context.getBean("userDao", DaoInterface.class);
My applicationContext.xml is as below:
<?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:mvc="http://www.springframework.org/schema/mvc"
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.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:component-scan base-package="model" />
<context:component-scan base-package="dao" />
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
<bean id="abcDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/demo"></property>
<property name="user" value="xxxx"></property>
<property name="password" value="xxxxx"></property>
<property name="minPoolSize" value="5" />
<property name="maxPoolSize" value="10" />
<property name="maxIdleTime" value="30000" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="abcDataSource" />
<property name="packagesToScan" value="model" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="abcTransactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="abcTransactionManager" />
</beans>
So, my question is, what need to be done in my application, so that I can get UserDao object using BaseDao class reference, not DaoInterface reference?
Some answers are there in this platform, but I am not getting the exact answer. Few solutions I have tried but can't solve.
Spring uses JDK dynamic proxies by default ($Proxy94), that can only proxy interfaces. That's basically why you can cast the userDao bean to the Dao interface, but not to the BaseDao class.
By the way you should prefer coding by interfaces.
However You can use <tx:annotation-driven proxy-target-class="true"/>
to instruct Spring to use CGLIB proxies.