Создание экземпляра компонента с помощью фабричного метода не удалось, а EntityManager имеет значение null

Я работаю над своим проектом (это игра). Теперь я пытаюсь изучить и добавить Spring Framework в свой проект. При добавлении Сервисов возникли ошибки. Я замечаю, что объектentManager имеет значение null (я думаю, по умолчанию), и я не знаю, как это исправить. Также не удалось создать экземпляр моего Bean с помощью фабричного метода. Не могу понять что не так и как это исправить.

Здесь я пытаюсь решить проблему с моей службой оценки. Ниже я добавлю несколько классов и описание. Если вам нужно что-то еще, я рад поделиться.

Мой список ошибок:


  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ / _` | \ \ \ \
 \/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.4.4)

2024-04-08 15:43:07.281  INFO 34026 --- [  restartedMain] sk.tuke.gamestudio.SpringClient          : Starting SpringClient using Java 21 on ip-154-224.wifi.tuke.sk with PID 34026 
2024-04-08 15:43:07.282  INFO 34026 --- [  restartedMain] sk.tuke.gamestudio.SpringClient          : No active profile set, falling back to default profiles: default
2024-04-08 15:43:07.302  INFO 34026 --- [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2024-04-08 15:43:07.302  INFO 34026 --- [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
2024-04-08 15:43:07.601  INFO 34026 --- [  restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2024-04-08 15:43:07.607  INFO 34026 --- [  restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 2 ms. Found 0 JPA repository interfaces.
2024-04-08 15:43:07.829  INFO 34026 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2024-04-08 15:43:07.833  INFO 34026 --- [  restartedMain] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2024-04-08 15:43:07.833  INFO 34026 --- [  restartedMain] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.44]
2024-04-08 15:43:07.861  INFO 34026 --- [  restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2024-04-08 15:43:07.861  INFO 34026 --- [  restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 558 ms
2024-04-08 15:43:07.939  INFO 34026 --- [  restartedMain] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
2024-04-08 15:43:07.965  INFO 34026 --- [  restartedMain] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 5.4.29.Final
2024-04-08 15:43:08.019  INFO 34026 --- [  restartedMain] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
2024-04-08 15:43:08.059  INFO 34026 --- [  restartedMain] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2024-04-08 15:43:08.104  INFO 34026 --- [  restartedMain] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2024-04-08 15:43:08.120  INFO 34026 --- [  restartedMain] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.PostgreSQL10Dialect
2024-04-08 15:43:08.371  INFO 34026 --- [  restartedMain] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2024-04-08 15:43:08.412  INFO 34026 --- [  restartedMain] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2024-04-08 15:43:08.426  INFO 34026 --- [  restartedMain] o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729
2024-04-08 15:43:08.508  WARN 34026 --- [  restartedMain] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
New JPA
2024-04-08 15:43:08.574  WARN 34026 --- [  restartedMain] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'consoleUI' defined in sk.tuke.gamestudio.SpringClient: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [sk.tuke.gamestudio.game.ConsoleUI]: Factory method 'consoleUI' threw exception; nested exception is java.lang.NullPointerException: Cannot invoke "javax.persistence.EntityManager.persist(Object)" because "this.entityManager" is null
2024-04-08 15:43:08.575  INFO 34026 --- [  restartedMain] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2024-04-08 15:43:08.576  INFO 34026 --- [  restartedMain] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
2024-04-08 15:43:08.578  INFO 34026 --- [  restartedMain] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
2024-04-08 15:43:08.579  INFO 34026 --- [  restartedMain] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
2024-04-08 15:43:08.584  INFO 34026 --- [  restartedMain] ConditionEvaluationReportLoggingListener : 

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2024-04-08 15:43:08.593 ERROR 34026 --- [  restartedMain] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'consoleUI' defined in sk.tuke.gamestudio.SpringClient: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [sk.tuke.gamestudio.game.ConsoleUI]: Factory method 'consoleUI' threw exception; nested exception is java.lang.NullPointerException: Cannot invoke "javax.persistence.EntityManager.persist(Object)" because "this.entityManager" is null
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:658) ~[spring-beans-5.3.5.jar:5.3.5]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:486) ~[spring-beans-5.3.5.jar:5.3.5]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1334) ~[spring-beans-5.3.5.jar:5.3.5]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177) ~[spring-beans-5.3.5.jar:5.3.5]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564) ~[spring-beans-5.3.5.jar:5.3.5]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) ~[spring-beans-5.3.5.jar:5.3.5]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.5.jar:5.3.5]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.5.jar:5.3.5]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.5.jar:5.3.5]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.5.jar:5.3.5]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:944) ~[spring-beans-5.3.5.jar:5.3.5]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[spring-context-5.3.5.jar:5.3.5]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.5.jar:5.3.5]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:144) ~[spring-boot-2.4.4.jar:2.4.4]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:769) ~[spring-boot-2.4.4.jar:2.4.4]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:761) ~[spring-boot-2.4.4.jar:2.4.4]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:426) ~[spring-boot-2.4.4.jar:2.4.4]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:326) ~[spring-boot-2.4.4.jar:2.4.4]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1313) ~[spring-boot-2.4.4.jar:2.4.4]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1302) ~[spring-boot-2.4.4.jar:2.4.4]
    at sk.tuke.gamestudio.SpringClient.main(SpringClient.java:16) ~[classes/:na]
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]
    at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-2.4.4.jar:2.4.4]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [sk.tuke.gamestudio.game.ConsoleUI]: Factory method 'consoleUI' threw exception; nested exception is java.lang.NullPointerException: Cannot invoke "javax.persistence.EntityManager.persist(Object)" because "this.entityManager" is null
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.3.5.jar:5.3.5]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653) ~[spring-beans-5.3.5.jar:5.3.5]
    ... 23 common frames omitted
Caused by: java.lang.NullPointerException: Cannot invoke "javax.persistence.EntityManager.persist(Object)" because "this.entityManager" is null
    at sk.tuke.gamestudio.service.ScoreServiceJPA.addScore(ScoreServiceJPA.java:19) ~[classes/:na]
    at sk.tuke.gamestudio.game.ConsoleUI.<init>(ConsoleUI.java:34) ~[classes/:na]
    at sk.tuke.gamestudio.SpringClient.consoleUI(SpringClient.java:21) ~[classes/:na]
    at sk.tuke.gamestudio.SpringClient$$EnhancerBySpringCGLIB$$60feade1.CGLIB$consoleUI$1(<generated>) ~[classes/:na]
    at sk.tuke.gamestudio.SpringClient$$EnhancerBySpringCGLIB$$60feade1$$FastClassBySpringCGLIB$$424405e0.invoke(<generated>) ~[classes/:na]
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) ~[spring-core-5.3.5.jar:5.3.5]
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331) ~[spring-context-5.3.5.jar:5.3.5]
    at sk.tuke.gamestudio.SpringClient$$EnhancerBySpringCGLIB$$60feade1.consoleUI(<generated>) ~[classes/:na]
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.3.5.jar:5.3.5]
    ... 24 common frames omitted


Process finished with exit code 0

Вот мой каталог с классами: введите сюда описание изображения

Вот мой класс ConsoleUI (не обращайте внимания на мои функции и меню):

package sk.tuke.gamestudio.game;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import sk.tuke.gamestudio.entity.Rating;
import sk.tuke.gamestudio.entity.Score;
import sk.tuke.gamestudio.service.*;

import java.util.Date;
import java.util.InputMismatchException;
import java.util.List;
import java.util.Scanner;


public class ConsoleUI
{
    @Autowired
    private ScoreService scoreService;

    @Autowired
    private RatingService ratingService;

    @Autowired
    private CommentService commentService;
    //private ScoreServiceJPA

    public ConsoleUI()
    {

        ratingService = new RatingServiceJPA();
        commentService = new CommentServiceJPA();
        scoreService = new ScoreServiceJPA();
        System.out.println("New JPA");
        scoreService.addScore(new Score("game", "username", 100, new Date()));
        System.out.println("SCORE ADDED!!!");
        ratingService.setRating(new Rating("game","player",101,new Date()));

        System.out.println("AAAAAAAAA");
        Intro();
    }

    private void Intro()
    {

        System.out.println(Color.YELLOW.getCode() + "  ");
        System.out.println("        ▄         ▄  ▄▄▄▄▄▄▄▄▄▄▄  ▄            ▄▄▄▄▄▄▄▄▄▄▄  ▄▄▄▄▄▄▄▄▄▄▄  ▄▄       ▄▄  ▄▄▄▄▄▄▄▄▄▄▄ \n" +
                "       ▐░▌       ▐░▌▐░░░░░░░░░░░▌▐░▌          ▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌▐░░▌     ▐░░▌▐░░░░░░░░░░░▌\n" +
                "       ▐░▌       ▐░▌▐░█▀▀▀▀▀▀▀▀▀ ▐░▌          ▐░█▀▀▀▀▀▀▀▀▀ ▐░█▀▀▀▀▀▀▀█░▌▐░▌░▌   ▐░▐░▌▐░█▀▀▀▀▀▀▀▀▀ \n" +
                "       ▐░▌       ▐░▌▐░▌          ▐░▌          ▐░▌          ▐░▌       ▐░▌▐░▌▐░▌ ▐░▌▐░▌▐░▌          \n" +
                "       ▐░▌   ▄   ▐░▌▐░█▄▄▄▄▄▄▄▄▄ ▐░▌          ▐░▌          ▐░▌       ▐░▌▐░▌ ▐░▐░▌ ▐░▌▐░█▄▄▄▄▄▄▄▄▄ \n" +
                "       ▐░▌  ▐░▌  ▐░▌▐░░░░░░░░░░░▌▐░▌          ▐░▌          ▐░▌       ▐░▌▐░▌  ▐░▌  ▐░▌▐░░░░░░░░░░░▌\n" +
                "       ▐░▌ ▐░▌░▌ ▐░▌▐░█▀▀▀▀▀▀▀▀▀ ▐░▌          ▐░▌          ▐░▌       ▐░▌▐░▌   ▀   ▐░▌▐░█▀▀▀▀▀▀▀▀▀ \n" +
                "       ▐░▌▐░▌ ▐░▌▐░▌▐░▌          ▐░▌          ▐░▌          ▐░▌       ▐░▌▐░▌       ▐░▌▐░▌          \n" +
                "       ▐░▌░▌   ▐░▐░▌▐░█▄▄▄▄▄▄▄▄▄ ▐░█▄▄▄▄▄▄▄▄▄ ▐░█▄▄▄▄▄▄▄▄▄ ▐░█▄▄▄▄▄▄▄█░▌▐░▌       ▐░▌▐░█▄▄▄▄▄▄▄▄▄ \n" +
                "       ▐░░▌     ▐░░▌▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌▐░▌       ▐░▌▐░░░░░░░░░░░▌\n" +
                "        ▀▀       ▀▀  ▀▀▀▀▀▀▀▀▀▀▀  ▀▀▀▀▀▀▀▀▀▀▀  ▀▀▀▀▀▀▀▀▀▀▀  ▀▀▀▀▀▀▀▀▀▀▀  ▀         ▀  ▀▀▀▀▀▀▀▀▀▀▀ \n" +
                "                                                                                           " +
                "                                                                                                                                                                              " +
                "                                                                                                                                                                                                                                                                 ");
        System.out.println("                                                                                                                            \n" +
                "  __  __  __  ____     __    ______  _____    ______  _____  _____    __     _____  __   _  ______  ______  ____    ______  \n" +
                " |  \/  \\|  ||    \\  _|  |_ |   ___||     |  |   ___|/     \\|     | _|  |_  |     ||  | | ||___   ||___   ||    |  |   ___| \n" +
                " |     /\\   ||     \\|_    _||   ___||     \\   `-.`-. |     ||     \\|_    _| |    _||  |_| | .-`.-`  .-`.-` |    |_ |   ___| \n" +
                " |____/  \\__||__|\\__\\ |__|  |______||__|\\__\\ |______|\\_____/|__|\\__\\ |__|   |___|  |______||______||______||______||______| \n" +
                "                                                                                                                            \n" +
                "                                                                                                                            ");
        System.out.println(" " + Color.RESET.getCode());


        Menu();
    }

    private void Menu()
    {
        System.out.println(Color.BRIGHT_GREEN.getCode() + "███╗   ███╗███████╗███╗   ██╗██╗   ██╗\n" +
                "████╗ ████║██╔════╝████╗  ██║██║   ██║\n" +
                "██╔████╔██║█████╗  ██╔██╗ ██║██║   ██║\n" +
                "██║╚██╔╝██║██╔══╝  ██║╚██╗██║██║   ██║\n" +
                "██║ ╚═╝ ██║███████╗██║ ╚████║╚██████╔╝\n" +
                "╚═╝     ╚═╝╚══════╝╚═╝  ╚═══╝ ╚═════╝ \n" +
                "                                      ");
        System.out.println();
        System.out.println("                            1. PLAY GAME");
        System.out.println("                            2. THE TOP PLAYERS LIST");
        System.out.println("                            3. THE RATING OF THE GAME");
        System.out.println("                            4. LEAVE" + Color.RESET.getCode());
        Scanner scanner = new Scanner(System.in);

        int input;
        do
        {
            System.out.println("Choose what you want: ");
            input = GetInput(scanner);
        }
        while (input <= 0 || input >= 5);

        switch (input) {
            case 1:
                System.out.println("Starting the game...");
                new UI();
                break;
            case 2:
                System.out.println("Viewing top players list...");
                List<Score> topScores = scoreService.getTopScores("Game");
                if (topScores.isEmpty()) {
                    System.out.println("There is no data.");
                } else {
                    for (Score score : topScores) {
                        System.out.println(score);
                    }
                }
                Menu();
                break;
            case 3:
                System.out.println("Viewing avarage rating...");
                RatingService ratingService = new RatingServiceJPA();
                int average = ratingService.getAverageRating("Game");
                if (average == 0) {
                    System.out.println("There is no ratings.");
                } else {
                    System.out.println("Game rating is: " + average);
                }
                System.out.println();
                Menu();
                break;
            case 4:
                System.out.println("Exiting...");
                return;
            default:
                System.out.println("Invalid input. Please enter a valid option.");
                break;
        }
    }

    private int GetInput(Scanner scanner) {
        int input = 0;
        while (true) {
            try {
                input = scanner.nextInt();
                break;
            } catch (InputMismatchException e) {
                System.out.println("Invalid input. Please enter an integer: ");
                scanner.nextLine();
            }
        }
        return input;
    }
}

Вот мой сценарий SpringClient:

package sk.tuke.gamestudio;

import sk.tuke.gamestudio.service.ScoreServiceJPA;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import sk.tuke.gamestudio.game.ConsoleUI;
import sk.tuke.gamestudio.game.UI;
import sk.tuke.gamestudio.service.*;

@SpringBootApplication
@Configuration
public class SpringClient {
    public static void main(String[] args) {
        SpringApplication.run(SpringClient.class);
    }

    @Bean
    public ConsoleUI consoleUI() {
        return new ConsoleUI();
    }

    @Bean
    public ScoreService scoreService() {
        return new ScoreServiceJPA();
    }

    @Bean
    public RatingService ratingService() {
        return new RatingServiceJPA();
    }

    @Bean
    public CommentService commentService() {
        return new CommentServiceJPA();
    }

    @Bean
    public UI ui(){
        return new UI();
    }
}

Теперь здесь будут классы сервисов Score:

Оценка.java:

package sk.tuke.gamestudio.entity;

import java.io.Serializable;
import java.util.Date;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Entity;
import javax.persistence.NamedQuery;


@Entity
@NamedQuery( name = "Score.getTopScores",
        query = "SELECT s FROM Score s WHERE s.game=:game ORDER BY s.points DESC")
@NamedQuery( name = "Score.resetScores", query = "DELETE FROM Score")

public class Score implements Serializable {

    @Id
    @GeneratedValue
    private int ident;

    private String game;

    private String player;

    private int points;

    private Date playedOn;

    public Score(String game, String player, int points, Date playedOn)
    {
        this.game = game;
        this.player = player;
        this.points = points;
        this.playedOn = playedOn;
    }

    public Score()
    {
    }

    public int getIdent()
    {
        return ident;
    }

    public void setIdent(int ident)
    {
        this.ident = ident;
    }

    public String getGame()
    {
        return game;
    }

    public void setGame(String game)
    {
        this.game = game;
    }

    public String getPlayer()
    {
        return player;
    }

    public void setPlayer(String player)
    {
        this.player = player;
    }

    public int getPoints()
    {
        return points;
    }

    public void setPoints(int points)
    {
        this.points = points;
    }

    public Date getPlayedOn()
    {
        return playedOn;
    }

    public void setPlayedOn(Date playedOn)
    {
        this.playedOn = playedOn;
    }

    @Override
    public String toString()
    {
        return "SCORE {" +
                "Game = '" + game + '\'' +
                ", Player = '" + player + '\'' +
                ", Score = " + points + " pts." +
                ", Last Time Online = " + playedOn +
                " }";
    }

}

Служба оценок:

package sk.tuke.gamestudio.service;

import sk.tuke.gamestudio.entity.Score;

import java.util.List;

public interface ScoreService
{
    void addScore(Score score) throws ScoreException;
    List<Score> getTopScores(String game) throws ScoreException;
    void reset() throws ScoreException;
}

ОценкаServiceJPA:

package sk.tuke.gamestudio.service;

import sk.tuke.gamestudio.entity.Score;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;
import java.util.List;

@Transactional
public class ScoreServiceJPA implements ScoreService {

    @PersistenceContext
    private EntityManager entityManager;


    @Override
    public void addScore(Score score) throws ScoreException {
        entityManager.persist(score);
    }

    @Override
    public List<Score> getTopScores(String game) throws ScoreException{
        return entityManager.createNamedQuery("Score.getTopScores").setParameter("game", game).setMaxResults(10).getResultList();

    }

    @Override
    public void reset() throws ScoreException{
        entityManager.createNamedQuery("Score.resetScores").executeUpdate();
    }
}

Исключение по баллам:

package sk.tuke.gamestudio.service;

public class ScoreException extends RuntimeException {
    public ScoreException(String message) {
        super(message);
    }

    public ScoreException(String message, Throwable cause) {
        super(message, cause);
    }
}

файл 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>sk.tuke</groupId>
    <artifactId>user-identity-rest</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <packaging>jar</packaging>

    <name>studio2024</name>
    <description>Gamestudio Project</description>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>14</source>
                    <target>14</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.4</version>
        <relativePath/>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>14</java.version>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>42.7.0</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>javax.persistence</groupId>
            <artifactId>javax.persistence-api</artifactId>
            <version>2.2</version>
        </dependency>
        <dependency>
            <groupId>javax.transaction</groupId>
            <artifactId>javax.transaction-api</artifactId>
            <version>1.3</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>RELEASE</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-boot-starter</artifactId>
            <version>3.0.0</version>
        </dependency>

    </dependencies>
</project>

Вот и все.

Я не видел, где в вашем классе нужно вставить EnitityManager — так что неудивительно, что это ScoreServiceJPA. Я пропустил место в коде, где вы его инициализируете, вы не добавили какую-то соответствующую часть своего кода в вопрос или вы пропустили вставку или инициализацию этого поля?

cyberbrain 08.04.2024 15:56

вам, возможно, придется определить ScoreRepository, который реализует ScoreServiceJPA. см. baeldung.com/spring-data-entitymanager

sge 09.04.2024 07:35
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
2
187
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Вы совершенно упускаете суть Внедрения зависимостей. Что делает для вас Spring, так это всякий раз, когда вы запрашиваете объект (используя @Autowired или @jakarta.inject.Inject или Инъекцию конструктора <- используйте это). Это означает, что когда вы используете свой код, это происходит с классом ConsoleUI:

@SpringBootApplication
@Configuration // this is useless remove it
public class SpringClient {
  public static void main(String[] args) {
    SpringApplication.run(SpringClient.class);
  }

  @Bean
  public ConsoleUI consoleUI() {
    return new ConsoleUI();
  }

  @Bean
  public ScoreService scoreService() {
    return new ScoreServiceJPA(); // 1
  }
}

и

@Transactional
public class ScoreServiceJPA implements ScoreService { // 2

  @PersistenceContext
  private EntityManager entityManager;

  @Override
  public void addScore(Score score) throws ScoreException {
    entityManager.persist(score);
  }

и

class ConsoleUI {
 @Autowired
 private ScoreService scoreService;


 public class ConsoleUI() {
  // this causes the issue // 3
  scoreService = new ScoreServiceJPA();
  // this is the important line 4
  scoreService.addScore(new Score("game", "username", 100, new Date()));
 }

На самом деле Spring сканирует все пакеты и классы на наличие общих аннотаций и создает дерево зависимостей, чтобы знать, какие объекты следует создавать в определенном порядке. На самом деле это не то, что происходит в фоновом режиме, но шаги должны четко указывать, почему вы получаете такую ​​ошибку.

  1. Из-за аннотации @Autowired в ConsoleUI Spring знает, что ему нужна некоторая реализация ScoreService (шаг //1).
  2. Поэтому он ищет некоторую зависимость (класс, реализующий такой интерфейс). Вы отметили его как @Bean внутри своей конфигурации. Внутри ScoreServiceJPA, который вы определили, требуется EntityManager с использованием @PersistentContext аннотации (по сути, это то же самое, что @Autowired или @Inject)
  3. Весенние комплекты EntityManager внутри вашего ScoreServiceJPA шага //2
  4. Spring теперь знает, что теперь у него есть экземпляр ScoreService для вашего ConsoleUI
  5. Spring создает экземпляр класса ConsoleUI, что означает, что он вызывает конструктор.
  6. вызывается конструктор и то, что внутри, называется
  7. в //3 вы создаете экземпляр вручную. Это настоящая проблема с вашим кодом. Spring ничего об этом не знает. Итак, во всех полях установлено значение null.
  8. затем в //4 вы вызываете addScore метод внутри конструктора ScoreServiceJPA, где EntityManager находится null, потому что вы создали его, а не Spring

Лучший способ заставить это работать — реорганизовать ваш код во внедрение конструктора и использовать обратные вызовы для инициализации вашего кода. Итак, ваш ConsoleUI превратится в следующее:

class ConsoleUI {
 private final ScoreService scoreService;


 public class ConsoleUI(ScoreService scoreService) {
   this.scoreService = scoreService;
 }

Следующим шагом будет использование аннотации PostConstruct или реализация интерфейса InitializingBean.

class ConsoleUI {
 private final ScoreService scoreService;


 public class ConsoleUI(ScoreService scoreService) {
   this.scoreService = scoreService;
 }

 @PostConstruct
 public void init() {
   scoreService.addScore(new Score("game", "username", 100, new Date()));
 }

Однако во время инициализации компонента Transactional может быть недоступно , поэтому вам придется заключить свой код в TransactionTemplate. Для логики CLI используйте CommandLineRunner интерфейс. С помощью этих небольших шагов вы сможете запустить свой код.

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