我有一个带Postgres DB的SpringMVC应用程序。我尝试添加Hibernate支持,但无法创建DAO bean。
完整堆栈跟踪
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'studentController' defined in file [C:\Users\user\IdeaProjects\sql-jdbc-school_app\target\sqlJdbcSchoolApp\WEB-INF\classes\ua\com\foxminded\sqljdbcschool\controllers\menu_controllers\StudentController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'hibernateStudentDao' is expected to be of type 'ua.com.foxminded.sqljdbcschool.dao.hibernate.HibernateStudentDao' but was actually of type 'jdk.proxy3.$Proxy64'
org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:578)
at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:530)
at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:170)
at javax.servlet.GenericServlet.init(GenericServlet.java:158)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1161)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1010)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4948)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5256)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:726)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:698)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:696)
at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1782)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:293)
at java.management/com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:814)
at java.management/com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:802)
at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:460)
at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:408)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:293)
at java.management/com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:814)
at java.management/com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:802)
at java.management/com.sun.jmx.remote.security.MBeanServerAccessController.invoke(MBeanServerAccessController.java:472)
at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1472)
at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1310)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1412)
at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:829)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:360)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:587)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:828)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:705)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:704)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'hibernateStudentDao' is expected to be of type 'ua.com.foxminded.sqljdbcschool.dao.hibernate.HibernateStudentDao' but was actually of type 'jdk.proxy3.$Proxy64'
2022年12月22日12:50:37.840严重[RMI TCP连接(3)-127.0.0.1] org.apache. Catalina .core.标准上下文. loadOn网络应用程序中的启动Servlet [调度程序][]抛出load()异常org.springframework.beans.factory.beanNotOfRequiredTypeException:名为“hibernateStudentDao”的Bean的类型应为“ua.com.foxminded.sqljdbcschool.dao. hib.hibernateStudentDao”,但实际上的类型为“jdk.proxy3.$Proxy64”
休眠的Spring配置
@Configuration
@ComponentScan("ua.com.foxminded.sqljdbcschool")
@PropertySource("classpath:properties.properties")
@EnableTransactionManagement
public class SpringConfig {
private final Environment environment;
@Autowired
public SpringConfig(Environment environment) {
this.environment = environment;
}
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(Objects.requireNonNull(environment.getProperty("driver")));
dataSource.setUrl(environment.getProperty("url"));
dataSource.setUsername(environment.getProperty("user"));
dataSource.setPassword(environment.getProperty("password"));
return dataSource;
}
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
return properties;
}
@Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan("ua.com.foxminded.sqljdbcschool.dto");
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
@Bean
public PlatformTransactionManager hibernateTransactionManager() {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory().getObject());
return transactionManager;
}
}
刀类
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import ua.com.foxminded.sqljdbcschool.dao.StudentDao;
import ua.com.foxminded.sqljdbcschool.dto.CourseDTO;
import ua.com.foxminded.sqljdbcschool.dto.StudentDTO;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Repository
public class HibernateStudentDao implements StudentDao {
private final SessionFactory sessionFactory;
@Autowired
public HibernateStudentDao(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@Override
@Transactional
public void create(StudentDTO student) {
Session session = sessionFactory.getCurrentSession();
session.persist(student);
}
@Override
@Transactional
public List<StudentDTO> getAll() {
Session session = sessionFactory.getCurrentSession();
return session.createQuery(" select s from StudentDTO s", StudentDTO.class).getResultList();
}
@Override
@Transactional
public StudentDTO searchById(Integer id) {
Session session = sessionFactory.getCurrentSession();
return session.get(StudentDTO.class, id);
}
@Override
@Transactional
public void delete(StudentDTO student) {
Session session = sessionFactory.getCurrentSession();
session.remove(student);
}
主计长
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import ua.com.foxminded.sqljdbcschool.dao.CourseDao;
import ua.com.foxminded.sqljdbcschool.dao.StudentDao;
import ua.com.foxminded.sqljdbcschool.dao.hibernate.HibernateCourseDao;
import ua.com.foxminded.sqljdbcschool.dao.hibernate.HibernateStudentDao;
import ua.com.foxminded.sqljdbcschool.dto.CourseDTO;
import ua.com.foxminded.sqljdbcschool.dto.StudentDTO;
import java.util.ArrayList;
import java.util.List;
@Controller
@RequestMapping("/menu/")
public class StudentController {
private static final String REDIRECT_MENU_SUCCESS = "redirect:success";
private final StudentDao studentDao;
private final CourseDao courseDao;
@Autowired
public StudentController(HibernateStudentDao studentDao, HibernateCourseDao courseDao) {
this.studentDao = studentDao;
this.courseDao = courseDao;
}
学生道界面
public interface StudentDao {
void create (StudentDTO student);
List<StudentDTO> getAll();
StudentDTO searchById(Integer id);
void delete (StudentDTO student);
void addStudentToGroup(StudentDTO student, Integer groupId);
void addStudentToCourse(StudentDTO student, CourseDTO course);
void deleteStudentFromCourse(StudentDTO student, CourseDTO course);
Map<Integer, Integer> searchGroupsByStudentCount(Integer studentCount);
void batchCreate(List<StudentDTO> students);
void batchAddStudentToGroup(List<StudentDTO> students);
我完全不知道该怎么修。
2条答案
按热度按时间wljmcqd81#
@Repository
注解标记的是接口,而不是实现。如果你想定制实现,你必须遵循一些预定义的步骤(包括命名/定位/标记所涉及的组件),请参考JPA文档。你可以从this article开始。cmssoen22#
@M.代努姆的决定。
通过向SpringConfig中的EnableTransactionManagement注解添加参数proxyTargetClass = true解决了此问题。
我也将控制器构造函数中的参数从Impl更改为与限定符的接口