Spring Failed to Autowiring because of proxy-target-class="true" and <aop:aspectj-autoproxy /> - spring

I have the following spring configuration:
<context:annotation-config />
<security:global-method-security jsr250-annotations="enabled" pre-post-annotations="enabled" proxy-target-class="true" />
<tx:annotation-driven />
<aop:aspectj-autoproxy />
<context:component-scan base-package="com.web,com.security" />
i have enabled proxy-target-class in global-method-security, because i want use #PreAuthorize annotation in the controller (i aware that spring team doesn't encourage this),
and using aop aspectJ as 'interceptor' in service when saving an object.
it seem that because the proxy configuration in global-method-security enabled and the default aop aspectj is using proxy implementation. it failed to autowiring the bean in all controller. proxying proxy ?
controller
#RequestMapping(value = "add")
#PreAuthorize("#securityPermission.validatePermission()")
public String add(Model model) {
//codes
}
my service class with #Aspect annotation
#SuppressWarnings("serial")
#Aspect
#Service
public class InterceptorServiceImpl extends BaseServiceImplementation implements InterceptorService {
#Autowired
private LogRepository logRepository;
#Around("execution(* com.repository.CardRequestRepository.save(..))")
#Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Exception.class,timeout = 30)
public Object checkProcess(ProceedingJoinPoint joinPoint) throws Throwable{
LOGGER.info("SERVICE : START Process checking Interceptor");
}
error logs :
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'approvalActivityController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.csl.cms.service.ApprovalActivityService com.csl.cms.web.ApprovalActivityController.approvalActivityService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'approvalActivityServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.csl.cms.repository.CardRequestRepository com.csl.cms.service.serviceimplementasi.ApprovalActivityServiceImpl.cardRequestRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cardRequestRepository': Post-processing of the FactoryBean's object failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy572]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy572
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:287)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106)
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.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:388)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:293)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:111)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4791)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5285)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.manager.ManagerServlet.start(ManagerServlet.java:1256)
at org.apache.catalina.manager.ManagerServlet.doGet(ManagerServlet.java:376)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:108)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:581)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:722)
Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy572]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy572
at org.springframework.aop.framework.Cglib2AopProxy.getProxy(Cglib2AopProxy.java:213)
at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:112)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:477)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:362)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:322)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:407)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.postProcessObjectFromFactoryBean(AbstractAutowireCapableBeanFactory.java:1598)
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:162)
... 65 more
Caused by: java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy572
at net.sf.cglib.proxy.Enhancer.generateClass(Enhancer.java:446)
at net.sf.cglib.transform.TransformingClassGenerator.generateClass(TransformingClassGenerator.java:33)
at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:285)
at org.springframework.aop.framework.Cglib2AopProxy.getProxy(Cglib2AopProxy.java:201)
... 72 more
repository class
public interface CardRequestRepository extends JpaRepository<CardRequest, Long>, CardRequestRepositoryCustom {
public List<CardRequest> findByCardholderId(Long cardholderId);
#Query("Select cr FROM CardRequest cr "
+ "LEFT JOIN FETCH cr.cardholder ch "
+ "LEFT JOIN FETCH ch.identityDocument "
+ "LEFT JOIN FETCH cr.program p "
+ "WHERE cr.id = :id")
public CardRequest findOneFetching(#Param("id") Long cardholderId);
}
public interface CardRequestRepositoryCustom {
public List<CardRequest> findCardRequestWithDatatablesCriterias(DatatablesCriterias criterias);
.....
service impl class
#SuppressWarnings("serial")
#Service
public class ApprovalActivityServiceImpl extends BaseServiceImplementasi implements ApprovalActivityService {
#Autowired
private ApprovalActivityRepository approvalActivityRepository;
...
#Autowired
private MessageSource messageSource;
#Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
public ApprovalActivity findOne(Long id) {
LOGGER.info("SERVICE : ApprovalActivity findOne id =" + id);
return approvalActivityRepository.findOne(id);
}
}
baseserviceimpl class
public abstract class BaseServiceImplementasi
implements Serializable
{
protected transient Logger LOGGER = Logger.getLogger(getClass());
}
is it possible using aop:aspectj-autoproxy and enable proxy-target-class at same time ? or anyone have another suggestion ? :)
Failed Autowire Issue resolved
as suggestion from #M.Deinum i resolved my autowiring issue, added proxy-target-class="true" attribute in :
<tx:annotation-driven />
<cache:annotation-driven />
<aop:aspectj-autoproxy />
and i remove #Service in the class with #Aspect annotation.
note : in the InterceptorServiceImpl i was using #Service because i want #Autowiring to call repository/service bean
aspect class issue that occurred :
it seem because i have removed the #Service annotation in my aspect class, the aop aspectj somehow did not executed, and no error in my logs.

I resolved my issue, it seem because the using of data jpa (JpaRepository) in my repository class.
here is my xml configuration :
<security:global-method-security jsr250-annotations="enabled" pre-post-annotations="enabled" proxy-target-class="true"/> //enabled proxy to use #preAuthorize in controller
<tx:annotation-driven />
<cache:annotation-driven />
<aop:aspectj-autoproxy />
<context:component-scan base-package="com.xxx.xxx.service.serviceimplementasi" />
<jpa:repositories base-package="com.csl.cms.repository" entity-manager-factory-ref="entityManagerFactory" transaction-manager-ref="transactionManager" />
data jpa configs :
<!--Spring Data JPA Configuration-->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" >
<property name="dataSource" ref="c3p0DataSource-1" />
<property name="packagesToScan" value="com.xxx.xxx.entity"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="${database.dialect}" />
<property name="showSql" value="true" />
<property name="generateDdl" value="true" />
</bean>
</property>
</bean>
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
</property>
</bean>
repository class :
public interface CardRequestRepository extends JpaRepository<CardRequest, Long>, CardRequestRepositoryCustom {
public List<CardRequest> findByCardholderId(Long cardholderId);
in CardRequestRepositoryCustom class, create a custom save method using entityManager, so it will not depends on JpaRepository class.
public class CardRequestRepositoryImpl implements CardRequestRepositoryCustom {
#PersistenceContext
private EntityManager em;
#Override
public CardRequest customSave(CardRequest cardRequest) {
em.persist(cardRequest);
return cardRequest;
}
i also changed my point cut class in my aspect class, use the repository custom class :
#SuppressWarnings("serial")
#Aspect
#Component
public class ApprovalInterceptorServiceImpl extends BaseServiceImplementasi implements ApprovalInterceptorService {
#Autowired
private LifecycleLogRepository lifecycleLogRepository;
#Autowired
private ApprovalDefinitionRepository approvalDefinitionRepository;
#Around("execution(* com.xxx.xxx.repository.repositoryimplementasi.CardRequestRepositoryImpl.customSave(..))")
#Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Exception.class,timeout = 30)
public CardRequest checkApprovalProcess(ProceedingJoinPoint joinPoint) throws Throwable{
LOGGER.info("SERVICE : START Approval Process checking Interceptor");
System.out.println("SERVICE : START Approval Process checking Interceptor");
Object messageParam[] = new Object[1];
Object[] objs = joinPoint.getArgs();
CardRequest cardRequest = (CardRequest) objs[0];
....
in the aop aspect class, using #Component to autowiring the service bean and do not extends the repository class using jpaRepository, instead use/create a custom repository class and entityManager to save an object. with this configuration and codes my proxy class problem fixed.
if i applied #Component, #Autowired and using jpaRepository in my aspect class, the repository bean class failed to autowiring. still does not know why it happen.

Related

Spring Transactional annotation giving CGLIB error

I am getting the following error when using the #Transactional annotation. Any ideas?
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myRepository' defined in file [myFile]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class myRepository]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:529)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:191)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:636)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at myRepository.main(myRepository.java:104)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class myRepository]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:217)
at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:111)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:477)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:362)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:322)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:409)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1520)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:521)
... 16 more
Caused by: java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
at org.springframework.cglib.proxy.Enhancer.emitConstructors(Enhancer.java:721)
at org.springframework.cglib.proxy.Enhancer.generateClass(Enhancer.java:499)
at org.springframework.cglib.transform.TransformingClassGenerator.generateClass(TransformingClassGenerator.java:33)
at org.springframework.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
at org.springframework.cglib.proxy.Enhancer.create(Enhancer.java:285)
at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:205)
Code:
#Repository
public class MyRepository {
private MyDao myDao;
#Autowired
public MyRepository(MyDao myDao) {
this.myDao = myDao
}
#Transactional
public void save(Object obj) {
if (obj.isNew())
myDao.create(obj)
}
}
XML:
<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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<!-- Enable Annotation based Declarative Transaction Management -->
<tx:annotation-driven proxy-target-class="true"
transaction-manager="transactionManager" />
<!-- Creating TransactionManager Bean, since JDBC we are creating of type DataSourceTransactionManager -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="dataSource"
class="com.mysql.jdbc.jdbc2.optional.MysqlDataSource" >
// datasource settings
</bean>
Superclass has no null constructors but no arguments were given
You need to autowire the field, and either remove the constructor or provide an additional no-argument constructor.
#Repository
public class MyRepository {
#Autowired
private MyDao myDao;
#Transactional
public void save(Object obj) {
if (obj.isNew())
myDao.create(obj)
}
}
}
Alternatively, use a #Transactional interface instead of a class so CGLIB doesn't need to be involved at all.
#Repository
#Transactional
public interface MyRepository {
void save(Object obj);
}
public class MyRepositoryImpl implements MyRepository {
private final MyDao myDao;
#Autowired
public MyRepository(MyDao myDao) {
this.myDao = myDao
}
public void save(Object obj) {
if (obj.isNew())
myDao.create(obj)
}
}
}

Spring 3 Annotations with hibernate CRUD operations : #Autowired not working as expected

I'm currently using Spring 3 annotations along with hibernate 3 for the database connectivity. I also have to be using spring tiles.
My spring-servlet.xml is:
<context:annotation-config />
<context:component-scan base-package="com.xxx.controller,com.xxx.dao,com.xxx.service" />
<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver"
id="viewResolver">
<property name="viewClass">
<value>
org.springframework.web.servlet.view.tiles2.TilesView
</value>
</property>
</bean>
<bean class="org.springframework.web.servlet.view.tiles2.TilesConfigurer"
id="tilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/plugin/impl/tiles/springtiles-defs.xml</value>
</list>
</property>
</bean>
//Is this required????
<!-- <bean id="MyDAO" class="com.xxxx.MyDAOImpl"></bean>
<bean id="MyService" class="com.xxxx.MyServiceImpl"></bean> -->
My controller class :
#Controller
public class myController {
#Autowired
private MyService myService;
public myController() {
}
#RequestMapping(value="/index.do", method = RequestMethod.GET)
protected ModelAndView Submit(HttpServletRequest request, HttpServletResponse response) throws Exception {
// TODO Auto-generated method stubs
System.out.println(" Inside the controller ");
</beans>
And my serviceImpl class:
#Service("MyService")
public class MyServiceImpl implements MyService{
#Autowired
MyDAO myDAO;
And my DaoImpl class :
#Repository/*("myDAO")*/
public class MyDAOImpl implements MyDAO{
List<String> clientList;
#Autowired
private SessionFactory sessionFactory;
private Session session;
private Session currentSession() {
return this.sessionFactory.getCurrentSession();
}
#Override
public List<ClientInfoBean> getClientList(String currentQrt) throws DataStoreException {
// TODO Auto-generated method stub
return (List<ClientInfoBean>) this.currentSession().
createCriteria("Select * from myTable);
}
It still gives the below exceptions.
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.xxx.service.MyService com.xxx.controller.MyController.MyService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.xxx.service.MyService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:288)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1116)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.xxx.service.MyService com.xxx.controller.MyController.MyService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.xxx.service.MyService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:514)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
... 97 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.xxx.service.MyService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:988)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:858)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:770)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:486)
... 99 more
So the problem is your packages:
You have definition of services and daos in: com.xxx.service and com.xxx.dao
and your implementation in: com.xxx.serviceImpl and com.xxx.daoImpl.
Add in also <context:component-scan base-package="com.xxx.serviceImpl,com.xxx.daoImpl"/>
Next problem you are facing is transactional management:
You havent defined it in spring configuration. This is an example how to do this:
<!-- Hibernate 3 Annotation SessionFactory Bean definition-->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.jdbc.batch_size">${batchSize}</prop>
</props>
</property>
</bean>
<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
And after this you need to mark a method or your service implementation as #Transactional to make spring care of this.
The exception is clearly telling you that the bean is not configured
NoSuchBeanDefinitionException: No qualifying bean of type [com.xxx.service.MyService]
Can you check the case of the bean names that you given in annotations are matching with the parameter name. myService vs MyService.
Also adding a setter might be a good idea as spring can call setter to inject the dependency instead of using Reflection to inject it.
When you define
#Service("MyService")
public class MyServiceImpl implements MyService{
}
or
#Repository("MyDAO")
public class MyDAOImpl implements MyDAO{
}
you are actually telling spring to create bean with the name "MyService" & "MyDAO"
when you define like
#Autowired
private MyService myService;
#Autowired
private MyDAO myDAO;
you are asking from spring to give bean(s) with the name "myService" & "myDAO".
Since spring creates bean with the name which is different from what are you asking, it is giving the error.
You have to keep name of the bean in the #Service & #Repository annotation same as the variable name for the Interface.
#Service("myService")
public class MyServiceImpl implements MyService{
}
private MyService myService;
As you qualified your service as "MyService" , you can add qualifier as below to find it. By default spring should autowire by type , so component scan should load your service. If you are defining beans partially in xml and expecting other services to be autowired, you have to add in your spring-servlet.xml
#Autowired
#Qualifier("MyService")
private MyService myService;
Also change your controller class as MyController instead of myController.
And remove the constructor myController(), spring will construct for you controller bean. Try to remove all your constructors in all your spring bean classes, spring will construct for you. For the beginning you can avoid qualifying the beans, remove the names in brackets( "MyService", "MyDao" etc....)
Use
#Service
public class MyServiceImpl implements MyService
Instead of
#Service("MyService")
public class MyServiceImpl implements MyService{

Spring: Can't move #Transactioanl annotation from DAO to Service layer

It the Transactional annotation is in the DAO layer it works, if I move it to the service layer, I get exception:
Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.adam.czibere.RestAPIController]: Illegal arguments for constructor; nested exception is java.lang.IllegalArgumentException: argument type mismatch
Here is my code:
CatalogDAOInterface:
public interface CatalogDAOInterface {
public List<Product> getAllProduct();
public List<Category> getAllCategories() ;
public List<Media> getAllMedias();
}
CatalogDAO:
#Repository
#SuppressWarnings({"unchecked", "rawtypes"})
public class CatalogDAO implements CatalogDAOInterface {
#Autowired private SessionFactory sessionFactory;
#Override
public List<Product> getAllProduct() {
Session session = sessionFactory.getCurrentSession();
List products = session.createQuery("from Product").list();
return products;
}
#Override
public List<Category> getAllCategories() {
Session session = sessionFactory.getCurrentSession();
List products = session.createQuery("from Category").list();
return products;
}
#Override
public List<Media> getAllMedias() {
Session session = sessionFactory.getCurrentSession();
List medias = session.createQuery("from Media").list();
return medias;
}
}
CatalogServiceInterface:
public interface CatalogServiceInterface {
public List<Category> getAllCategories();
public List<Product> getAllProducts();
public List<Media> getAllMedias();
}
CatalogService:
#Service
public class CatalogService implements CatalogServiceInterface{
#Autowired
private CatalogDAO catalogDAO;
#Transactinal
#Override
public List<Product> getAllProducts() {
return catalogDAO.getAllProduct();
}
#Transactinal
#Override
public List<Category> getAllCategories() {
return catalogDAO.getAllCategories();
}
#Transactinal
#Override
public List<Media> getAllMedias() {
return catalogDAO.getAllMedias();
}
}
servlet-context.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:mvc="http://www.springframework.org/schema/mvc"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<!-- Enable #Controller annotation support -->
<mvc:annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving
up static resources in the ${webappRoot}/resources directory -->
<mvc:resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by #Controllers to .jsp resources
in the /WEB-INF/views directory -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<context:component-scan base-package="com.adam.czibere" />
<!-- <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" -->
<!-- destroy-method="close"> -->
<!-- <property name="driverClassName" value="com.mysql.jdbc.Driver" /> -->
<!-- <property name="url" value="jdbc:mysql://localhost:3306/pizzashop" /> -->
<!-- <property name="username" value="root" /> -->
<!-- <property name="password" value="czadam" /> -->
<!-- <property name="validationQuery" value="SELECT 1" /> -->
<!-- </bean> -->
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="net.sourceforge.jtds.jdbc.Driver" />
<property name="url" value="jdbc:jtds:sqlserver://something" />
<property name="username" value="something" />
<property name="password" value="something" />
<property name="validationQuery" value="SELECT 1" />
</bean>
<!-- Hibernate Session Factory -->
<bean id="mySessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="packagesToScan">
<array>
<value>com.adam.czibere</value>
</array>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQLDialect
</value>
</property>
</bean>
<!-- Hibernate Transaction Manager -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="mySessionFactory" />
</bean>
<!-- Activates annotation based transaction management -->
<tx:annotation-driven transaction-manager="transactionManager" />
</beans>
The stack trace:
exception
javax.servlet.ServletException: Servlet.init() for servlet appServlet threw exception
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
java.lang.Thread.run(Thread.java:724)
root cause
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'catalogAPIController' defined in file [C:\Users\czadam\Documents\workspace 2.0\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\wtpwebapps\SalesWizard\WEB-INF\classes\com\adam\czibere\CatalogAPIController.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.adam.czibere.CatalogAPIController]: Illegal arguments for constructor; nested exception is java.lang.IllegalArgumentException: argument type mismatch
org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:288)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1035)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:939)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:631)
org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:588)
org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:645)
org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:508)
org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:449)
org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:133)
javax.servlet.GenericServlet.init(GenericServlet.java:160)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
java.lang.Thread.run(Thread.java:724)
root cause
org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.adam.czibere.CatalogAPIController]: Illegal arguments for constructor; nested exception is java.lang.IllegalArgumentException: argument type mismatch
org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:158)
org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:110)
org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:280)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1035)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:939)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:631)
org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:588)
org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:645)
org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:508)
org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:449)
org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:133)
javax.servlet.GenericServlet.init(GenericServlet.java:160)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
java.lang.Thread.run(Thread.java:724)
root cause
java.lang.IllegalArgumentException: argument type mismatch
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
java.lang.reflect.Constructor.newInstance(Constructor.java:526)
org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:147)
org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:110)
org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:280)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1035)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:939)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:631)
org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:588)
org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:645)
org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:508)
org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:449)
org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:133)
javax.servlet.GenericServlet.init(GenericServlet.java:160)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
java.lang.Thread.run(Thread.java:724)
Part of My Controller:
#Controller
#RequestMapping(value = "api", produces = "application/json")
public class CatalogAPIController {
CatalogService catalogService;
private static final int BUFFER_SIZE = 4096;
#Autowired
public CatalogAPIController(CatalogService catalogService) {
this.catalogService = catalogService;
}
// get all categories
#RequestMapping(value = "category/all", produces = "application/json;charset=UTF-8")
#ResponseBody
public String getAllCategories() {
JSONArray categoryArray = new JSONArray();
for (Category cat : catalogService.getAllCategories()) {
JSONObject categoryJSON = new JSONObject();
try {
categoryJSON.put("id", cat.getId());
categoryJSON.put("name", cat.getName());
categoryJSON.put("imageMediaID", cat.getImageMediaID());
categoryJSON.put("parentID", cat.getParent().getId());
// Media
JSONArray mediaArray = new JSONArray();
for (Media item : cat.getMedias()) {
if (item != null) {
mediaArray.put(item.getId());
}
}
categoryJSON.put("mediaIDs", mediaArray);
categoryJSON.put("modifiedDate", cat.getModifiedDate());
categoryArray.put(categoryJSON);
} catch (JSONException e) {
e.printStackTrace();
return "Error: " + e.getMessage();
}
}
return categoryArray.toString();
}
}
When Spring is applying the #Transactional annotation internally, it creates a proxy class which wraps your service class.
So when your service bean is created in your application context, you are getting an object that is not of type CatalogService but some Proxy$1 class.
This Proxy$1 class will not extend CatalogService but it will implement CatalogServiceInterface. Therefore, when your CatalogAPIController bean gets created, it attempts to call its constructor with your Proxy$1 object which is the wrong type as your constructor expects a class.
So if you were to change your controller to use the interface instead of the implementation, then I believe your problems will disappear. This is because Proxy$1 DOES implement CatalogServiceInterface.
The moral of the story: ALWAYS use the interface if you reference your implementation (for if you ever decide to provide a different implementation (e.g. CatalogService2 which also implements CatalogServiceInterface, you can only plug that into your CatalogAPIController if its constructor is using the interface rather than the class (and essentially this is what's happening when you specify #Transactional.
Hope that makes sense.
two thing caught my attention
1.
#Transactinal
is it a typo or are you importing another annotation, it should be #Transactional
2.
why aren't you using the interfaces if you're already defining them?
instead of
#Autowired
public CatalogAPIController(CatalogService catalogService) {
this.catalogService = catalogService;
}
change it to
#Autowired
public CatalogAPIController(CatalogServiceInterface catalogService) {
this.catalogService = catalogService;
}
same applies to dao interface.
I don't understand the relation between moving transactional from one place to the other. See if that helps
This is what I can think of with the details you've provided. I believe you don't have the CGLIB libraries on your classpath. As such, for Spring to apply #Transactional behavior, it proxies your annotated class with JDK proxies. JDK proxies use interfaces, they cannot proxy base classes. As such, the direct superclass of a proxy is java.lang.reflect.Proxy.
In this case, your CatalogService bean will be wrapped in a proxy whose class is something like Proxy$1. When Spring tries to instantiate your #Controller class, CatalogAPIController, through reflection using the constructor
#Autowired
public CatalogAPIController(CatalogService catalogService) {
this.catalogService = catalogService;
}
it will fail because the argument passed to the Constructor#newInstance(Object...) method will not match the parameter type CatalogService since Proxy$1 is not a sub type of CatalogService.
The reason this didn't happen when you were annotating the DAO, I believe is that your DAO class is not on the component-scan package that applied #Transactional behavior. So it might have appeared as though the #Transactional was working but it wasn't. Because #Transactional wasn't working, no proxy was created and therefore Spring didn't complain about injecting this field
#Autowired
private CatalogDAO catalogDAO;
in your service class.
One possible solution is to do what Luis recommended and change your parameter types to the interface as JDK proxies to implement the interfaces, ie. the interfaces are supertypes of the Proxy$1 class instance generated to wrap your bean.
Another solution is to provide the CGLIB jars on your classpath. Spring will detect them and use them. It will then be able to proxy your class by base class instead of interface. You can find the libraries here.
Don't forget to tell Spring to proxy the target class with
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />

Having issues autowiring a sessionfactory bean with spring mvc and hibernate

I am trying to implement auto-wiring into my project, but it seems that my application isn't seeing my SessionFactory definition in my application-context.xml when I am running it.
I'm probably missing something really obvious, though I've tried several solutions from posts having similar issues with no success.
I am using Spring MVC and Hibernate.
Here is my application-context.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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:annotation-config />
<context:component-scan base-package="arlua" />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/pages/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<bean id="serverDatasource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>oracle.jdbc.driver.OracleDriver</value>
</property>
<property name="url">
<value>url</value>
</property>
<property name="username">
<value>${user}</value>
</property>
<property name="password">
<value>${pwd}</value>
</property>
</bean>
<bean id="propertyPlaceholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>
<bean id="mySessionFactory"
class="org.springframework.orm.hibernate3.annotation.LocalSessionFactoryBean">
<property name="mappingResources">
<list>
<value>mapping/user_info.hbm.xml</value>
<value>mapping/login.hbm.xml</value>
<value>mapping/linked_accounts.hbm.xml</value>
<value>mapping/application_instance.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<property name="dataSource" ref="serverDatasource"/>
</bean>
<bean id = "userInfoDaoImpl" class="arlua.dao.impl.UserInfoDaoImpl">
<property name="sessionFactory" ref="mySessionFactory"/>
</bean>
<bean id = "loginDaoImpl" class="arlua.dao.impl.LoginDaoImpl">
<property name="sessionFactory" ref="mySessionFactory"/>
</bean>
<bean id = "linkedAccountsDaoImpl" class="arlua.dao.impl.LinkedAccountsDaoImpl">
<property name="sessionFactory" ref="mySessionFactory"/>
</bean>
<!--
<bean id = "applicationInstanceDaoImpl" class="arlua.dao.impl.ApplicationInstanceDaoImpl">
<property name="sessionFactory" ref="mySessionFactory"/>
</bean>
-->
<!-- ************* TRANSACTION MANAGEMENT USING AOP **************** -->
<bean id="myTransactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="mySessionFactory"/>
</bean>
<aop:config>
<aop:pointcut id="allMethods" expression="execution(* arlua.dao.TableEntityFetchDao.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="allMethods"/>
</aop:config>
<tx:advice id="txAdvice" transaction-manager="myTransactionManager">
<tx:attributes>
<tx:method name="saveEntity"
propagation = "REQUIRES_NEW"
isolation = "READ_COMMITTED"
rollback-for = "Exception"/>
<tx:method name="updateEntity"
propagation = "REQUIRES_NEW"
isolation = "READ_COMMITTED"
rollback-for = "Exception"/>
<tx:method name="getEntity"
propagation = "REQUIRES_NEW"
isolation = "READ_COMMITTED"
rollback-for = "Exception"/>
<tx:method name="getAllEntities"
propagation = "REQUIRES_NEW"
isolation = "READ_COMMITTED"
rollback-for = "Exception"/>
</tx:attributes>
</tx:advice>
</beans>
Here is the controller class where I am trying to autowire.
package arlua.controller;
import arlua.dao.TableEntityFetchDao;
import arlua.dao.impl.ApplicationInstanceDaoImpl;
import arlua.service.SearchCriteria;
import arlua.service.UserAction;
import arlua.tables.ApplicationInstanceTable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;
#Controller
#SessionAttributes
public class SearchAppController{
#Autowired public ApplicationInstanceDaoImpl applicationInstanceDaoImpl;
private String input;
private ApplicationInstanceTable oldApp, newApp;
#RequestMapping(value = "/search_app_instance", method = RequestMethod.POST)
public String mySearchMethod(#ModelAttribute("search_criteria") SearchCriteria search){
input = search.getInput();
if(input != null)
input = input.toUpperCase();
return "redirect:search_app_instance";
}
#RequestMapping("/search_app_instance")
public ModelAndView mySuccessMethod(){
ModelAndView model = new ModelAndView("search_app_instance");
//Check and Make sure that the app exists
//ApplicationContext factory =
// new ClassPathXmlApplicationContext("spring-namespace.xml");
//TableEntityFetchDao urd = (TableEntityFetchDao)factory.getBean("applicationInstanceDaoImpl");
try{
ApplicationInstanceTable app =
(ApplicationInstanceTable) applicationInstanceDaoImpl.getEntity(input);
oldApp = app;
//Load app data into table
model.addObject("app_id", app.getApplication_id());
model.addObject("name", app.getName());
model.addObject("default_exp_period", app.getDefault_expiration_period());
model.addObject("server", app.getServer());
model.addObject("description", app.getDescription());
model.addObject("active", app.getActive());
model.addObject("conn_string", app.getConn_string());
model.addObject("creation_date", app.getCreation_date().getTime());
model.addObject("error", "");
}
catch(Exception e){
if(input != null)
{
model.addObject("error", "Application could not be found.");
input = "";
}
}
return model;
}
#RequestMapping(value = "/app_actions", method = RequestMethod.POST)
public String userActionsMethod(#ModelAttribute("user_action") UserAction action,
#ModelAttribute("app_info") ApplicationInstanceTable app_info){
if(action.getAction().equals("update_info"))
{
newApp = app_info;
return "redirect:update_app_info";
}
return "redirect:search_app_instance";
}
#RequestMapping("/update_app_info")
public ModelAndView updateInfoMethod(){
ModelAndView model = new ModelAndView("search_app_instance");
ApplicationContext factory =
new ClassPathXmlApplicationContext("spring-namespace.xml");
TableEntityFetchDao urd = (TableEntityFetchDao)factory.getBean("applicationInstanceDaoImpl");
newApp.setApplication_id(oldApp.getApplication_id());
newApp.setCreation_date(oldApp.getCreation_date());
urd.updateEntity(newApp);
model.addObject("msg", "Application '" + newApp.getApplication_id() + "' modified successfully.");
return model;
}
}
ApplicationInstanceDaoImpl Class
package arlua.dao.impl;
import arlua.dao.TableEntityFetchDao;
import arlua.tables.ApplicationInstanceTable;
import java.util.List;
import javax.annotation.Resource;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Repository;
#Repository("applicationInstanceDaoImpl")
public class ApplicationInstanceDaoImpl extends TableEntityFetchDao{
public SessionFactory mySessionFactory;
#Resource(name = "mySessionFactory")
public void setMySessionFactory(SessionFactory mySessionFactory){
this.mySessionFactory = mySessionFactory;
}
public void saveEntity(Object applicationInstance) {
this.mySessionFactory.getCurrentSession().save((ApplicationInstanceTable)applicationInstance);
}
public ApplicationInstanceTable getEntity(Object application_id) {
return (ApplicationInstanceTable)this.mySessionFactory.getCurrentSession().
get(ApplicationInstanceTable.class, (String)application_id);
}
public void updateEntity(Object applicationInstance) {
this.mySessionFactory.getCurrentSession().update((ApplicationInstanceTable)applicationInstance);
}
public void deleteEntity(Object applicationInstance) {
this.mySessionFactory.getCurrentSession().delete((ApplicationInstanceTable)applicationInstance);
}
public List<?> getAllEntities() {
return this.mySessionFactory.getCurrentSession().createQuery
("FROM application_instance").list();
}
}
TableEntityFetchDao class
package arlua.dao;
import java.util.List;
import org.hibernate.SessionFactory;
/*
This class will serve as a generic blueprint for all of the other data access implementation classes
that are used to perform basic CRUD operations on the arlua tables (ie UserInfoDaoImpl).
*/
public abstract class TableEntityFetchDao {
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory){
this.sessionFactory = sessionFactory;
}
public abstract void saveEntity(final Object entity);
public abstract Object getEntity(final Object key);
public abstract void updateEntity(final Object entity);
public abstract void deleteEntity(final Object entity);
public abstract List<?> getAllEntities();
}
Here is most of my stack trace.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping#0': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'searchAppController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: public arlua.dao.impl.ApplicationInstanceDaoImpl arlua.controller.SearchAppController.applicationInstanceDaoImpl; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'applicationInstanceDaoImpl': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'mySessionFactory' is defined
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:580)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:276)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:197)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4206)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4705)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1057)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:840)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1057)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:463)
at org.apache.catalina.core.StandardService.start(StandardService.java:525)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:754)
at org.apache.catalina.startup.Catalina.start(Catalina.java:595)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'searchAppController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: public arlua.dao.impl.ApplicationInstanceDaoImpl arlua.controller.SearchAppController.applicationInstanceDaoImpl; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'applicationInstanceDaoImpl': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'mySessionFactory' is defined
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1074)
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:291)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1075)
at org.springframework.web.servlet.handler.AbstractUrlHandlerMapping.registerHandler(AbstractUrlHandlerMapping.java:383)
at org.springframework.web.servlet.handler.AbstractUrlHandlerMapping.registerHandler(AbstractUrlHandlerMapping.java:362)
at org.springframework.web.servlet.handler.AbstractDetectingUrlHandlerMapping.detectHandlers(AbstractDetectingUrlHandlerMapping.java:82)
at org.springframework.web.servlet.handler.AbstractDetectingUrlHandlerMapping.initApplicationContext(AbstractDetectingUrlHandlerMapping.java:58)
at org.springframework.context.support.ApplicationObjectSupport.initApplicationContext(ApplicationObjectSupport.java:119)
at org.springframework.web.context.support.WebApplicationObjectSupport.initApplicationContext(WebApplicationObjectSupport.java:72)
at org.springframework.context.support.ApplicationObjectSupport.setApplicationContext(ApplicationObjectSupport.java:73)
at org.springframework.context.support.ApplicationContextAwareProcessor.invokeAwareInterfaces(ApplicationContextAwareProcessor.java:106)
at org.springframework.context.support.ApplicationContextAwareProcessor.postProcessBeforeInitialization(ApplicationContextAwareProcessor.java:85)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:394)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1413)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
... 26 more
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: public arlua.dao.impl.ApplicationInstanceDaoImpl arlua.controller.SearchAppController.applicationInstanceDaoImpl; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'applicationInstanceDaoImpl': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'mySessionFactory' is defined
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:502)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:282)
... 46 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'applicationInstanceDaoImpl': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'mySessionFactory' is defined
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:300)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1074)
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:291)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:844)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:786)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:703)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:474)
... 48 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'mySessionFactory' is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:527)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1083)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:274)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:435)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:409)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:541)
at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:156)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:297)
... 59 more
Edit: I ended up fixing my problem by autowiring into the interface TableEntityFetchDao rather than the class that was implementing it, ApplicationInstanceDaoImpl.
So, this
#Autowired public ApplicationInstanceDaoImpl applicationInstanceDaoImpl;
Became this
#Autowired public TableEntityFetchDao applicationInstanceDao;
And that seemed to fix my problem.
Instead of:
#Resource(name = "mySessionFactory")
public void setMySessionFactory(SessionFactory mySessionFactory){
this.mySessionFactory = mySessionFactory;
}
Use:
#Autowired
private SessionFactory mySessionFactory;
EDIT
As of the bellow comment:
Not sure why method is not working but my guess is that the parent TableEntityFetchDao class has the setter of session factory, then ApplicationInstanceDaoImpl - child class overrides it and spring for some reason does not like it, if TableEntityFetchDao would be an interface, setter would be injected, as #Resource serves the same purpose as #Autowired difference is that #Resource allows to specify the name of the bean which is injected, and #Autowire allows you mark the bean as not required.
To get #Resource working I would try to remove setter method from the parent class. Either way it makes no sense of having it there as it is not used. Also sessionFactory field. This can be removed as well. Then class contains only abstract methods and can be made an interface. Also I would annotate TableEntityFetchDao with #Service annotation for better understanding that it is a service-layer class.
#Resource(name = "mySessionFactory")
public void setMySessionFactory(SessionFactory mySessionFactory){
this.mySessionFactory = mySessionFactory;
}
try as #Autowired
public void setMySessionFactory(SessionFactory mySessionFactory){
this.mySessionFactory = mySessionFactory;
}
modify your code from the below code snippet in your spring configuration file
<bean id="mySessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="mappingLocations">
<list>
<value>mapping/user_info.hbm.xml</value>
<value>mapping/login.hbm.xml</value>
<value>mapping/linked_accounts.hbm.xml</value>
<value>mapping/application_instance.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<property name="dataSource" ref="serverDatasource"/>
I hope this code will work for you, and let me know , if still you are facing the problem

java.lang.IllegalArgumentException: 'sessionFactory' or 'hibernateTemplate' is required in spring+hibernate

I am doing spring + hibernate apllication. When I run the application on tomcat server I am getting some exception. Below is my code.
This is my bean config file.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>WEB-INF/database/db.properties</value>
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<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="dataSource">
<ref bean="dataSource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="mappingResources">
<list>
<value>Employee.hbm.xml</value>
</list>
</property>
</bean>
<bean id="employeeBo" class="com.saggezza.employee.bo.impl.EmployeeBoImpl">
<property name="employeeDao" ref="employeeDao" />
</bean>
<bean id="employeeDao" class="com.saggezza.employee.dao.impl.EmployeeDaoImpl">
<constructor-arg ref="sessionFactory"></constructor-arg>
</bean>
this is my dao class.
public class EmployeeDaoImpl extends HibernateDaoSupport implements EmployeeDao {
private SessionFactory sessionFactory;
public EmployeeDaoImpl(SessionFactory sessionfactory){
this.sessionFactory=sessionfactory;
}
#Override
public List<Employee> getEmployeeDetails() {
return getHibernateTemplate().find("from Employee");
}
}
Here another class employeeBo is calling the employeeDaoImpl.
when I run thisI am getting the below exception.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'employeeBo' defined in ServletContext resource [/WEB-INF/spring/EmployeeBean.xml]: Cannot resolve reference to bean 'employeeDao' while setting bean property 'employeeDao'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'employeeDao' defined in ServletContext resource [/WEB-INF/spring/EmployeeBean.xml]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: 'sessionFactory' or 'hibernateTemplate' is required
Can anybody help to resolve this. I have tried a lot and google it as well.But did get the solution.
If you have two configuration files, you duplicates 'sessionFactory' definition. Remove one of the 'sessionFactory' definitions . You would have got duplicate bean definition exception before the IllegalArgumentException.
Edit: After your comment,
public class EmployeeDaoImpl extends HibernateDaoSupport implements EmployeeDao {
public EmployeeDaoImpl(SessionFactory sessionfactory){
setSessionFactory(sessionfactory);
}
#Override
public List<Employee> getEmployeeDetails() {
return getHibernateTemplate().find("from Employee");
}
}
or get rid of constructor in above code and inject 'sessionFactory' using setter injection.See org.springframework.orm.hibernate3.support.HibernateDaoSupport.setSessionFactory(SessionFactory). I prefer later approach.
I think the problem is the type of SessionFactory you are injecting in EmployeeDaoImpl does not match with the type of the SessionFactory you used in the class.
Can you check it?
This is an old question so must be solved now but still if someone comes across this problem. Following is solution.
You can use Hibernate DAO Support by extending HibernateDAOSupport class and overriding its afterPropertiesSet() method.
This method is called in HibernateDAO support and at that time since sessionFactory is null it is throwing this error. In your custom class you can set this property explicitly and then call the same method of Parent Class (i.e. HibernateDAOSupport's addProperties() method)
package com.techcielo.spring4.hibernate.template;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Component;
#Component("hibernateTemplate")
public class Hibernate4CustomTemplate extends HibernateTemplate{
#Autowired(required=true)
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
System.out.println("Setting SessionFactory");
this.sessionFactory = sessionFactory;
super.setSessionFactory(sessionFactory);
}
#Override
public void afterPropertiesSet() {
System.out.println("Checking if properties set..."+this.sessionFactory);
setSessionFactory(sessionFactory);
super.afterPropertiesSet();
}
}
Following can be used for sample!
I had the same problem and fix it by using Autowired constructor with EntityManagerFactory. Keyur answer is correct
#Service
class EmployeeDaoImpl #Autowired constructor(
factory: EntityManagerFactory
) : HibernateDaoSupport(), EmployeeDao {
init {
if (factory.unwrap(SessionFactory::class.java) == null) {
throw NullPointerException("factory is not a hibernate factory")
}
setSessionFactory(factory.unwrap(SessionFactory::class.java))
}
...
}

Resources