Я новичок в Spring Boot и JPA. Я разрабатываю приложение с использованием этих технологий, но столкнулся с проблемой. Когда я запускаю приложение, я сталкиваюсь с исключением «Не управляемый тип», связанным с моим классом сущностей User.
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2023-07-31 15:11:07.786 ERROR 15380 --- \[ main\] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'loginController' defined in file \[C:\\1-project\\target\\classes\\com\\example1\\project\\Login\\LoginController.class\]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userService' defined in file \[C:\\1-project\\target\\classes\\com\\example1\\project\\User\\UserService.class\]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepository' defined in com.example1.project.User.UserRepository defined in @EnableJpaRepositories declared on Application: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class com.example1.project.User.User
Класс сущности пользователя:
package com.example1.project.User;
import jakarta.persistence.*;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
@Entity
@Table(name = "users")
public class User
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotBlank
private String name;
@Email
@NotBlank
private String email;
@NotBlank
private String username;
@NotBlank
private String password;
public User() {}
// Getters and Setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
Пользовательский репозиторий:
package com.example1.project.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
User findByUsername(String username);
}
Пользовательская служба:
package com.example1.project.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserService {
private final UserRepository userRepository;
@Autowired
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public User authenticateUser(String username, String password) {
User user = userRepository.findByUsername(username);
if (user != null) {
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
if (passwordEncoder.matches(password, user.getPassword())) {
return user;
}
}
return null;
}
// Implement service methods using the repository methods
public List<User> getAllUsers() {
return userRepository.findAll();
}
public User getUserById(Long id) {
return userRepository.findById(id).orElse(null);
}
public User saveUser(User user) {
user.setPassword(new BCryptPasswordEncoder().encode(user.getPassword()));
return userRepository.save(user);
}
public void deleteUser(Long id) {
userRepository.deleteById(id);
}
}
ЛогинКонтроллер:
package com.example1.project.Login;
import com.example1.project.User.User;
import com.example1.project.User.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/login")
public class LoginController {
private final UserService userService;
@Autowired
public LoginController(UserService userService) {
this.userService = userService;
}
@PostMapping
public ResponseEntity<?> login(@RequestBody LoginRequest loginRequest) {
// Extract username and password from the login request payload
String username = loginRequest.getUsername();
String password = loginRequest.getPassword();
User authenticatedUser = userService.authenticateUser(username, password);
if (authenticatedUser != null) {
// User is authenticated, return user data or a token (if using token-based authentication)
return ResponseEntity.ok(authenticatedUser);
} else {
// Invalid credentials, return an error response
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid username or password");
}
}
}
Сначала я подозревал, что может быть проблема с тем, как я аннотировал свои классы сущностей, поэтому я перепроверил их, чтобы убедиться, что использовал правильные аннотации. Я ожидал, что если аннотации будут правильными, приложение будет работать без ошибок «Неуправляемый тип». Однако, несмотря на то, что мои классы сущностей кажутся правильно аннотированными, ошибка все еще сохраняется.
Это моя структура проекта:
src
├── main
│ └── java
│ └── com.example1.project
│ └──Login(subpackage)
│ └──Order(subpackage)
│ └──Product(subpackage)
│ └──User(subpackage)
│ └──Application(main class)
│ └──CorsConfig(class)
│ └──SecurityConfiguration(class)
└── test
Новая ошибка:
В моей таблице mysql с именем product эта таблица имеет 4 столбца с именами id, description, name, price, я хотел отправить от почтальона в mysql эти данные:
{
"name": "Case",
"price": 19.99
}
Но когда я нажимаю «Отправить», я получаю 401 Unauthorized в почтальоне, URL-адрес http://localhost:8080/api/products.
Я добавил класс под названием SecurityConfiguration, думая, что если я установлю имя пользователя «пользователь» и пароль «пароль», я могу перейти в PostMan → Авторизация и добавить пользователя и пароль в качестве учетных данных, но я получаю ту же ошибку:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import javax.sql.DataSource;
@Configuration
public class SecurityConfiguration {
@Bean
public InMemoryUserDetailsManager userDetailsService() {
UserDetails user = User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
}
Это мой класс ProductController:
package com.example1.project.Product;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/products")
public class ProductController {
private final ProductService productService;
@Autowired
public ProductController(ProductService productService) {
this.productService = productService;
}
@GetMapping
public List<Product> getAllProducts() {
return productService.getAllProducts();
}
@GetMapping("/{id}")
public Product getProductById(@PathVariable Long id) {
return productService.getProductById(id);
}
@GetMapping("/search")
public List<Product> searchProducts(@RequestParam String keyword) {
return productService.searchProducts(keyword);
}
@PostMapping
public Product addProduct(@RequestBody Product product) {
return productService.saveProduct(product);
}
@PutMapping("/{id}")
public Product updateProduct(@PathVariable Long id, @RequestBody Product product) {
product.setId(id);
return productService.saveProduct(product);
}
@DeleteMapping("/{id}")
public void deleteProduct(@PathVariable Long id) {
productService.deleteProduct(id);
}
}
Когда я запускаю свое приложение, я получаю это в консоли:
2023-08-01T18:05:24.940+03:00 INFO 13520 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2023-08-01T18:05:24.941+03:00 INFO 13520 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2023-08-01T18:05:24.943+03:00 INFO 13520 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 2 ms
2023-08-01T18:13:33.563+03:00 WARN 13520 --- [l-1 housekeeper] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Thread starvation or clock leap detected (housekeeper delta=7m32s427ms71µs900ns).
Он находится в пакете com.example1.project.
Можете ли вы поместить аннотацию @Repository поверх класса UserRepository?
я добавил его сейчас, но я все еще получаю ту же ошибку
Как вы создаете таблицу «пользователи» в базе данных? Используете ли вы аннотацию @EntityScan или какие-то инструменты миграции? Если вы используете @EntityScan, убедитесь, что он сканирует объекты в правильном пакете.
я использую @EntityScan(basePackages = "com.example1.project.User") в своем основном классе, поскольку сущность пользователя находится в com.example1.package, подпакете пользователя, я также использую @EnableJpaRepositories(basePackages = "com.example1.project. Пользователь")
Сканирование объекта не требуется, если структура вашего проекта правильная, @SpringBootApplication позаботится обо всем
Если ваш класс @SpringBootApplication находится в пакете com.example1.project (и его нет в каком-то подпакете), вам не нужны все остальные аннотации, на самом деле они даже работают против автоматической настройки. Добавление @Repository в репозиторий Spring Data бесполезно, оно только добавляет шума. Пожалуйста, опубликуйте структуру вашего проекта.
могу ли я добавить структуру проекта в комментарии или в свой пост?
то, что сказал AKhil, было правильным, я удалил Entity scan, и у меня больше нет этой ошибки, но теперь я получаю другую
Вы обновили свой пост с новой ошибкой? Если нет, ты можешь это сделать
я обновил его сейчас




В вашем классе конфигурации безопасности вам также нужен bean-компонент SecurityFilterChain, который разрешает аутентификацию httpBasic, это причина, по которой вы получаете 401 неавторизованный, думаю, я был полезен
Просто взгляните на документацию Конфигурация в модуле HttpSecurity
Где находится ваш
@SpringBootApplicationаннотированный класс? Это должно быть в пакетеcom.example1.project, а не в каком-то подпакете.