Ошибка Spring Boot JPA: «Не управляемый тип: класс com.example1.project.User.User

Я новичок в 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).

Где находится ваш @SpringBootApplication аннотированный класс? Это должно быть в пакете com.example1.project, а не в каком-то подпакете.

M. Deinum 31.07.2023 17:11

Он находится в пакете com.example1.project.

CosmaPOP 31.07.2023 17:45

Можете ли вы поместить аннотацию @Repository поверх класса UserRepository?

Akhil 31.07.2023 18:06

я добавил его сейчас, но я все еще получаю ту же ошибку

CosmaPOP 31.07.2023 18:13

Как вы создаете таблицу «пользователи» в базе данных? Используете ли вы аннотацию @EntityScan или какие-то инструменты миграции? Если вы используете @EntityScan, убедитесь, что он сканирует объекты в правильном пакете.

SwathiP 31.07.2023 18:48

я использую @EntityScan(basePackages = "com.example1.project.User") в своем основном классе, поскольку сущность пользователя находится в com.example1.package, подпакете пользователя, я также использую @EnableJpaRepositories(basePackages = "com.example1.project. Пользователь")

CosmaPOP 31.07.2023 19:16

Сканирование объекта не требуется, если структура вашего проекта правильная, @SpringBootApplication позаботится обо всем

Akhil 31.07.2023 19:29

Если ваш класс @SpringBootApplication находится в пакете com.example1.project (и его нет в каком-то подпакете), вам не нужны все остальные аннотации, на самом деле они даже работают против автоматической настройки. Добавление @Repository в репозиторий Spring Data бесполезно, оно только добавляет шума. Пожалуйста, опубликуйте структуру вашего проекта.

M. Deinum 31.07.2023 20:00

могу ли я добавить структуру проекта в комментарии или в свой пост?

CosmaPOP 31.07.2023 20:05

то, что сказал AKhil, было правильным, я удалил Entity scan, и у меня больше нет этой ошибки, но теперь я получаю другую

CosmaPOP 31.07.2023 20:45

Вы обновили свой пост с новой ошибкой? Если нет, ты можешь это сделать

Akhil 01.08.2023 16:16

я обновил его сейчас

CosmaPOP 01.08.2023 17:43
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Версия Java на основе версии загрузки
Версия Java на основе версии загрузки
Если вы зайдете на официальный сайт Spring Boot , там представлен start.spring.io , который упрощает создание проектов Spring Boot, как показано ниже.
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
0
12
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В вашем классе конфигурации безопасности вам также нужен bean-компонент SecurityFilterChain, который разрешает аутентификацию httpBasic, это причина, по которой вы получаете 401 неавторизованный, думаю, я был полезен

Просто взгляните на документацию Конфигурация в модуле HttpSecurity

Другие вопросы по теме