问题描述
我正在使用没有Spring Boot的Spring MVC.
I am using Spring MVC without Spring Boot.
我正在尝试在Java类(无xml)中设置Spring DATA JPA存储库.
I am trying to setup Spring DATA JPA Repository in java classes, no xml.
我做到了,如图所示.项目3 https://www.baeldung.com/带有jpa的持久层
I did it as shown here. Item No. 3 https://www.baeldung.com/the-persistence-layer-with-spring-and-jpa
又不想工作,我不知道怎么回事.
and does not want to work, I don’t know what’s the matter.
日志包含以下消息:
org.springframework.beans.factory.UnsatisfiedDependencyExcep tion: Error creating bean with name 'userServiceImpl': Unsatisfied dependency expressed through field 'userRepository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionExcept ion: No qualifying bean of type 'com.testjpaspring.repository.UserRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(req uired=true)}
将您的项目放置在github https://github.com/romanych2021/TestJpaSpring
Place your project on github https://github.com/romanych2021/TestJpaSpring
UserRepository
package com.testjpaspring.repository;
import com.testjpaspring.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
User findByUsername (String username);
}
UserService
package com.testjpaspring.service;
import com.testjpaspring.model.User;
import org.springframework.stereotype.Service;
@Service
public interface UserService {
User findByUsername (String username);
}
UserServiceImpl
package com.testjpaspring.service;
import com.testjpaspring.model.User;
import com.testjpaspring.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.transaction.Transactional;
@Service
@Transactional
public class UserServiceImpl implements UserService{
@Autowired
UserRepository userRepository;
@Override
public User findByUsername(String username) {
return userRepository.findByUsername(username);
}
}
MyController
package com.testjpaspring.controller;
import com.testjpaspring.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class MyController {
@Autowired
UserService userService;
@ResponseBody
@GetMapping(value = "/")
public String home () {
return userService.findByUsername("roma").getUsername();
}
}
RootConfig
package com.testjpaspring.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.sql.DataSource;
import java.util.Properties;
@EnableWebMvc
@Configuration
@EnableTransactionManagement
@ComponentScan({"com.testjpaspring.repository", "com.testjpaspring.service"})
public class RootConfig implements WebMvcConfigurer {
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan("com.testjpaspring.model");
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalProperties());
return em;
}
@Bean
public DataSource dataSource(){
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/testjpaspring?serverTimezone=UTC&useSSL=false");
dataSource.setUsername( "root" );
dataSource.setPassword( "1234" );
return dataSource;
}
@Bean
public PlatformTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
return new PersistenceExceptionTranslationPostProcessor();
}
Properties additionalProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL8Dialect");
return properties;
}
}
配置
package com.testjpaspring.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;
import java.util.Properties;
@Configuration
@EnableWebMvc
@ComponentScan({"com.testjpaspring.controller"})
public class Config implements WebMvcConfigurer{
@Bean
public FreeMarkerConfigurer freeMarkerConfigurer() {
FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
configurer.setTemplateLoaderPath("/WEB-INF/templates");
configurer.setDefaultEncoding("UTF-8");
Properties properties = new Properties();
properties.setProperty("default_encoding", "UTF-8");
configurer.setFreemarkerSettings(properties);
return configurer;
}
@Bean
public ViewResolver getViewResolver(){
FreeMarkerViewResolver viewResolver = new FreeMarkerViewResolver();
viewResolver.setSuffix(".ftl");
viewResolver.setContentType("text/html;charset=UTF-8");
viewResolver.setCache(false);
return viewResolver;
}
}
POM.XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.testjpaspring</groupId>
<artifactId>TestJpaSpring</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${encoding}</encoding>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<failOnMissingWebXml>false</failOnMissingWebXml>
<java.version>1.8</java.version>
<encoding>UTF-8</encoding>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>5.2.9.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Spring Framework-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.3.4.RELEASE</version>
</dependency>
<!-- Hibernate-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.4.21.Final</version>
</dependency>
<!-- Остальные-->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.30</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
</dependencies>
</project>
推荐答案
您丢失了
@EnableJpaRepositories(basePackages = "com.testjpaspring.repository")
在您的 RootConfig
类上.
事实上,该类应如下所示:
As a matter of fact, the class should look like this:
@Configuration
@ComponentScan("com.testjpaspring.service")
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "com.testjpaspring.repository")
public class RootConfig {
// Keep method as are
}
它与您的WebMVC安装程序无关.
It has nothing todo with your WebMVC Setup.
当我刚刚意识到您发现自己(之前没有单击其他5条评论)时,这里有一个解释:
As I just realized that you found out yourself (didn't click the 5 more comments before), here's an explanation:
这是Spring Boot最近通常要做的事情.您需要明确指定程序包名称,因为注释处理器将向下查看其中带有注释的config类的程序包.
This is something normally done by Spring Boot these days. You need to explicitly specify the package name as the annotation processor would look down the package in which the annotated config class is in.
没有注释或明确的包名,Spring Data JPA存储库从不引导,因此在上下文中不可用.如果您将 @Repository
添加到类中,则将它们添加为Spring Beans.但是, UserRepository
是声明性接口,而不是类.
Without the annotation or the explicit package name, Spring Data JPA repositories are never bootstrapped and as such, not available in the context.Adding @Repository
to them makes them Spring Beans IF you would have added that to a class. However, the UserRepository
is a declarative interface, not a class.
此外,您可以从 UserRepository
中删除 @Repository
,这对于JPA Repository来说是不需要的.
Also, you can remove @Repository
from the UserRepository
, this not needed for JPA Repositories to work.
这篇关于如何设置Spring Data JPA存储库?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!