I'm building a project where I'm using Spring Boot and JavaFX. In the main scene I push a button that calls a method in a service and this one calls a method in the repository, but I'm getting an error saying the repository is null.
I have read a lot of answer because there are a lot of posts describing the same problem and tried everything I found but can't get it to work.
Please can you help me?
Here is the error:
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml@19/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1857)
at javafx.fxml@19/javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1724)
at javafx.base@19/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at javafx.base@19/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
at javafx.base@19/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at javafx.base@19/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at javafx.base@19/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at javafx.base@19/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base@19/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base@19/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base@19/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base@19/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base@19/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at javafx.base@19/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.base@19/javafx.event.Event.fireEvent(Event.java:198)
at javafx.graphics@19/javafx.scene.Node.fireEvent(Node.java:8923)
at javafx.controls@19/javafx.scene.control.Button.fire(Button.java:203)
at javafx.controls@19/com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:207)
at javafx.controls@19/com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274)
at javafx.base@19/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:247)
at javafx.base@19/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at javafx.base@19/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
at javafx.base@19/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at javafx.base@19/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at javafx.base@19/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at javafx.base@19/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base@19/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base@19/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base@19/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base@19/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base@19/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at javafx.base@19/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.base@19/javafx.event.Event.fireEvent(Event.java:198)
at javafx.graphics@19/javafx.scene.Scene$MouseHandler.process(Scene.java:3894)
at javafx.graphics@19/javafx.scene.Scene.processMouseEvent(Scene.java:1887)
at javafx.graphics@19/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2620)
at javafx.graphics@19/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:411)
at javafx.graphics@19/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:301)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at javafx.graphics@19/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:450)
at javafx.graphics@19/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:424)
at javafx.graphics@19/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:449)
at javafx.graphics@19/com.sun.glass.ui.View.handleMouseEvent(View.java:551)
at javafx.graphics@19/com.sun.glass.ui.View.notifyMouse(View.java:937)
at javafx.graphics@19/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics@19/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.reflect.InvocationTargetException
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 com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:77)
at jdk.internal.reflect.GeneratedMethodAccessor60.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at javafx.base@19/com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:275)
at javafx.fxml@19/com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:84)
at javafx.fxml@19/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1854)
... 46 more
Caused by: java.lang.NullPointerException: Cannot invoke "com.lista.project.repository.AlimentoRepository.findAll()" because "this.alimentoRepository" is null
at com.lista.project.service.AlimentoService.getAll(AlimentoService.java:19)
at com.lista.project.controller.MainController.getAllAlimentos(MainController.java:48)
... 57 more
Here is the structure of the project:
Here is the Application class:
@SpringBootApplication
@EnableAutoConfiguration
@EnableJpaRepositories(basePackages = {"com.lista.project.repository", "com.lista.project.repository.custom"})
//@EnableTransactionManagement
@EntityScan(basePackages = {"com.lista.project.*"})
@ComponentScan(basePackages = {"com.lista.project.*"})
public class MiListaCompraApplication extends SpringBootServletInitializer{
public static void main(String[] args) {
SpringApplication.run(MiListaCompraApplication.class, args);
MainController.main(args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(MiListaCompraApplication.class);
}
}
Here is the main scene controller:
@RestController // Don't think I really need this annotation
public class MainController extends Application {
AlimentoService alimentoService = new AlimentoService();
@Override
public void start(Stage primaryStage) {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/com/lista/project/scene/Main.fxml"));
//First I was defining the controller in the Main.fxml file, but tried to change into this as I read somewhere
loader.setController(this);
Parent parent = loader.load();
Scene scene = new Scene(parent,400,400);
primaryStage.setScene(scene);
primaryStage.setTitle("Mi lista de la compra");
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
public List<Alimento> getAllAlimentos() {
List<Alimento> response = alimentoService.getAll();
System.out.println("Bien!");
return response;
}
}
Here is the service:
@Service
public class AlimentoService {
@Autowired
private AlimentoRepository alimentoRepository;
public List<Alimento> getAll() {
return alimentoRepository.findAll();
}
}
Here is the Repository:
@Component //Don't think I need this annotation, but also tried @Repository just in case
public interface AlimentoRepository extends AlimentoRepositoryI, JpaRepository<Alimento, Integer> {
}
More parts of the same repository:
@Component //Don't think I need this annotation, but also tried @Repository just in case
public interface AlimentoRepositoryI {
}
@Component //Here is where I actually have to put the annotation, right? (Tried @Repository too)
public class AlimentoRepositoryImpl implements AlimentoRepositoryI {
}
My entity:
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "alimento")
public class Alimento {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private int id;
@NotNull
@Column(name = "name", length = 100, nullable = false)
private String name;
}
The FXML file:
<AnchorPane minHeight="400.0" minWidth="400.0" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1">
<children>
<!-- Initially, the controller was defined here -->
<Button fx:id="btnAlimentos" layoutX="30.0" layoutY="26.0" mnemonicParsing="false" onAction="#getAllAlimentos" text="Alimentos" />
<Button fx:id="btnPlatos" layoutX="30.0" layoutY="75.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="70.0" text="Platos" />
</children>
</AnchorPane>
Properties file:
server.port=8090
server.servlet.context-path=
spring.jmx.enabled= false
spring.jpa.open-in-view=false
spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext
spring.jpa.properties.hibernate.format_sql=false
spring.jpa.show-sql=false
spring.datasource.url = jdbc:mysql://localhost:3306/mimenu?useSSL=false&useUnicode=true&useLegacyDatetimeCode=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#spring.main.web-application-type=none
logging.level.org.hibernate.sql= error
debug=true
My POM.xml file:
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.lista</groupId>
<artifactId>MiListaCompra</artifactId>
<version>0.0.1</version>
<packaging>war</packaging>
<name>MiListaCompra</name>
<description>Generador de lista de la compra con JavaFX y SpringBoot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- <dependency> -->
<!-- <groupId>org.springframework.boot</groupId> -->
<!-- <artifactId>spring-boot-starter</artifactId> -->
<!-- </dependency> -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>