I'm new to Spring and I'm trying to autowire a generic DAO. Unfortunately, I'm getting an error. I tried to search info based on it, but most solutions state to use @Qualifier annotation which in my opinion is against what I want to achieve.
So below some code (I'll get rid of that class parameter once I deal with current issue):
DAO
public interface GenericDAO<T> {
T save(T entity, Class<T> tClass);
List<T> findAll(Class<T> tClass);
List<T> findAllByKeyword(String keyword, Class<T> tClass);
T findById(int id, Class<T> tClass);
void deleteById(int id, Class<T> tClass);
}
public class GenericDAOImpl<T> implements GenericDAO<T> {
SessionFactory sessionFactory;
public GenericDAOImpl(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@Override
@Transactional
public T save(T entity, Class<T> tClass) {
//body
}
//other methods
}
@Repository
public class FooDAOImpl extends GenericDAOImpl<Foo> {
@Autowired
public FooDAOImpl(SessionFactory sessionFactory) {
super(sessionFactory);
}
Service
public interface GenericService<T> {
T save(T entity, Class<T> tClass);
List<T> findAll(Class<T> tClass);
List<T> findAllByKeyword(String keyword, Class<T> tClass);
T findById(int id, Class<T> tClass);
void deleteById(int id, Class<T> tClass);
}
public class GenericServiceImpl<T, T_DAO extends GenericDAO<T>> implements GenericService<T> {
private final T_DAO dao;
public GenericServiceImpl(T_DAO dao) {
this.dao = dao;
}
@Override
public T save(T entity, Class<T> tClass) {
return dao.save(entity, tClass);
}
// other methods
}
@Service
public class FooServiceImpl extends GenericServiceImpl<Foo, FooDAOImpl> {
@Autowired
public FooServiceImpl(FooDAOImpl fooDAOImpl) {
super(fooDAOImpl);
}
}
}
And error thrown below:
javax.servlet.ServletException: Servlet.init() for servlet [dispatcher] threw exception
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707)
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.base/java.lang.Thread.run(Thread.java:834)
Root Cause
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'fooServiceImpl' defined in class path resource [*/*/*/service/FooServiceImpl.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'fooDAOImpl' is expected to be of type '*.*.*.repository.FooDAOImpl' but was actually of type 'com.sun.proxy.$Proxy76'
org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:797)
org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:227)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1356)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1203)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:556)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516)
org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324)
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322)
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:897)
org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:879)
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:551)
org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:702)
org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:668)
org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:716)
org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:591)
org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:530)
org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:170)
javax.servlet.GenericServlet.init(GenericServlet.java:158)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707)
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.base/java.lang.Thread.run(Thread.java:834)
Root Cause
org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'fooDAOImpl' is expected to be of type '*.*.*.repository.FooDAOImpl' but was actually of type 'com.sun.proxy.$Proxy76'
org.springframework.beans.factory.support.DefaultListableBeanFactory.checkBeanNotOfRequiredType(DefaultListableBeanFactory.java:1736)
org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1713)
org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1273)
org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1227)
org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:884)
org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:788)
org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:227)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1356)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1203)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:556)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516)
org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324)
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322)
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:897)
org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:879)
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:551)
org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:702)
org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:668)
org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:716)
org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:591)
org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:530)
org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:170)
javax.servlet.GenericServlet.init(GenericServlet.java:158)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707)
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.base/java.lang.Thread.run(Thread.java:834)
CodePudding user response:
The error is that spring has failed to create the bean customerServiceImpl because
customerServiceImpl expect a dependency of type CustomerDAOImpl and spring has injected a dependency of com.sun.proxy.$Proxy76
Bean named 'customerDAOImpl' is expected to be of type
'com.smartdigit.zalewski.repository.CustomerDAOImpl' but was actually of type
'com.sun.proxy.$Proxy76'
You have to change your FooServiceImpl class in order to get a dependency of type FooDAOInterface and not an implementation of it.
Someting like:
public class FooServiceImpl extends GenericServiceImpl<> {
@Autowired
public FooServiceImpl(FooDAOInterface fooDAO) {
super(fooDAOImpl);
}
}
You have to pass an interface type in the FooServiceImpl constructor in order to spring autowired it when the spring context has been initilized.
CodePudding user response:
Hi Error is coming due to wrong dependency got passed in constructor.
Please use like this.
@Service
public class FooServiceImpl extends GenericServiceImpl<Foo, FooDAO> {
private final FooDAO fooDAO;
@Autowired
public FooServiceImpl(FooDAO fooDAO) {
this.fooDAO = fooDAO
}
}
If a bean has one constructor, you can omit the @Autowired
@Service
public class FooServiceImpl extends GenericServiceImpl<Foo, FooDAO> {
private final FooDAO fooDAO;
public FooServiceImpl(FooDAO fooDAO) {
this.fooDAO = fooDAO
}
}
Note: FooDAO should be your interface
