0

I want to autowire a service in my FXML Controller class in order for me to save an input after I press a button in the UI

I have tried to autowire the service in a Terminal class that implements CommandLineRunner and I save my data to the database successfully.

However the autowire doesn't seem to work in a FXML Controller. Is that possible anyway??

Here is my repository:

package com.unibul.repositories;

import com.unibul.entities.Persona;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface PersonaRepository extends JpaRepository<Persona, Long> {

}

This is the service inteface:

package com.unibul.services.personas;

import com.unibul.entities.Persona;


public interface PersonaService {

    Persona add(Persona persona);
}

And this is the service implementation class

package com.unibul.services.personas;

import com.unibul.entities.Persona;
import com.unibul.repositories.PersonaRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;

@Service
@Transactional
public class PersonaServiceImpl implements PersonaService {

    private final PersonaRepository personaRepository;

    @Autowired
    public PersonaServiceImpl(PersonaRepository personaRepository) {

        this.personaRepository = personaRepository;
    }

    @Override
    public Persona add(Persona persona) {
        Persona persistedPersona;
        persistedPersona = personaRepository.save(persona);
        return persistedPersona;
    }
}

Here is the FXML Controller class

package com.unibul.controllers;

@Component
public class PersonasController implements Initializable {

    @Autowired
    private PersonaService personaService;

    @FXML
    private JFXButton btn_submit;

    @Override
    public void initialize(URL url, ResourceBundle rb) {

        //Handles all events on mouse clicks and actions
        eventHandler();

    }

    //Handles all events on mouse clicks and actions
    private void eventHandler() {

        btn_submit.setOnMouseClicked((MouseEvent event) -> {
            Persona persona = new Persona("some data");
            personaService.add(persona);

        }
    }
}

When i run the program I get a null pointer exception at personaService.add(persona);

I have checked and the personaService returns null

If it is correctly autowired it should return something...

Any suggestions what I am doing wrong?

EDIT: Here is how I set the controller Factory

@SpringBootApplication
public class MarketingApplication extends Application {
    private ConfigurableApplicationContext springContext;
    private Parent root;

    @Override
    public void init() throws Exception {
        springContext = SpringApplication.run(MarketingApplication.class);
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/layouts/Main.fxml"));
        fxmlLoader.setControllerFactory(springContext::getBean);
        root = fxmlLoader.load();
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        Scene scene = new Scene(root, 800, 600);
        primaryStage.setMinWidth(380);
        primaryStage.setMinHeight(500);

        Image image = new Image("/images/icon.png");
        primaryStage.getIcons().add(image);

        primaryStage.setScene(scene);
        primaryStage.show();
    }

    @Override
    public void stop() throws Exception {
        springContext.stop();
    }


    public static void main(String[] args) {
        launch(MarketingApplication.class, args);
    }
}
Rangel Stoilov
  • 106
  • 1
  • 10
  • Probably a duplicate of https://stackoverflow.com/questions/40539310/dependency-injection-and-javafx (If not, please show the code that shows how you are getting the controller instance from the spring bean factory) – James_D Oct 09 '17 at 20:00
  • I don't have much experience with Spring boot (more with "classic" Spring), but how does the application context here know which packages to scan for component annotations (`@Service`, `@Bean`, etc)? If I follow you correctly, the application context knows to create a `PersonasController` bean but it is not creating a `PersonaService` bean. Is it possible it is just not scanning the `com.unibul.services.personas` package? – James_D Oct 10 '17 at 01:41
  • I belive that the `@SpringBootApplication` finds all classes annotated with `@Configuration`,`@Component`, `@Repository`, `@Service`, `@Controller`, `@RestController` automatically. Yout `MainApplication.class` should be in the main folder and it should find all the other classes with no problem. – Rangel Stoilov Oct 10 '17 at 07:15
  • What package is `MarketingApplication` in? – James_D Oct 10 '17 at 11:42

0 Answers0