Null Pointer exception on JPA method access

I have a class instantiating a Grid as follows:

Grid client = new Grid<>(Client.class);
ClientService cserv = new ClientService();
ArrayList clients = new ArrayList<>();
clients = cserv.getAll();
client.setItems(clients);

The clients = cserv.getAll returns Null Pointer exception

The ClientService :

@Service
public class ClientService {

@Autowired
ClientRepository clientRepository;

@Transactional(readOnly = true)
public ArrayList<Client> getAll() {
    return clientRepository.findAll();
}

The ClientRepository:

@Repository
public interface ClientRepository extends JpaRepository<Client,Integer> {

ArrayList<Client> findAll();

}

Hi Jorge

You cannot instantiate the ClientService yourself, using new ClientService()! If you do that then the clientRepository will not be autowired and therefore be null at the time of calling getAll().

You need to autowire the ClientService into your view! Never instantiate a Spring-Component (classes annotated with @Service or @Controller or @Repository - which are all extentions of @Component) yourself.

I did that before Autowiring, but it gave me the same error

Failed to instantiate [com.packagename.myapp.spring.ProductForm]
: Constructor threw exception; nested exception is java.lang.NullPointerException’

Here is with Autowire

@Route
public class ProductForm extends VerticalLayout {
public DBRegConnectionManager cm;

@Autowired
ClientService cservice;

public ProductForm() throws SQLException {
    cm = new DBRegConnectionManager("trident");
    add(new TextField("Name"));
    
    add(new TextArea("Description"));
    
    NumberField price = new NumberField("Price");
    price.setSuffixComponent(new Span("$"));
    price.setStep(0.01);
    add(price);
    
    add(new DatePicker("Available"));
    
    ComboBox<String> category = new ComboBox<>("Category");
    category.setItems("A","B","C");
    add(category);
    
    Button save = new Button("Save");
    save.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
    Button cancel = new Button("Cancel");

// cancel.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
HorizontalLayout buttons = new HorizontalLayout(save,cancel);
add(buttons);
Grid client = new Grid<>(Client.class);
// ClientService cserv = new ClientService();
// ArrayList clients = new ArrayList<>();
// clients = new getAllCstmrs();
client.setItems(cservice.getAll());
// HorizontalLayout layout = new HorizontalLayout();
// layout.add(client);
add(client);

Edit: wait I was confused by your code markdown i didnt see @route.
You use field injection instead of constructor injection. When doing field injection, the clientService will be autowired AFTER the constructor. But you want to use it within the constructor

@Route
public class ProductForm extends VerticalLayout {

	@Autowired	
	public ProductForm(ClientService clientService) {
		// clientService is now not null in the constructor!
		clientService.getAll(); // works
	}
	
}

If it’s important to you that you use field injection, you can move everything in the constructor to a [post-constructor]
(https://stackoverflow.com/q/3406555/3441504)

@Route
public class ProductForm extends VerticalLayout {

	@Autowired	ClientService clientService
	
	public ProductForm() {
		// clientService is null here
	}
	
	@PostConstruct
	public postConstructor(){
		// clientService is not null here
		clientService.getAll(); // works
	}
}

Edit: wait I was confused by your code markdown i didnt see @route.
You use field injection instead of constructor injection. When doing field injection, the clientService will be autowired AFTER the constructor. But you want to use it within the constructor

@Route
public class ProductForm extends VerticalLayout {

	// this is called constructor injection. 
	// You don't even need the @Autowired annotation but I like it because it shows me that some autowiring is happening
	@Autowired	
	public ProductForm(ClientService clientService) { 
		// clientService is now not null in the constructor!
		clientService.getAll(); // works
	}
	
}

If it’s important to you that you use field injection, you can move everything in the constructor to a [post-constructor]
(https://stackoverflow.com/q/3406555/3441504)

@Route
public class ProductForm extends VerticalLayout {

	@Autowired	ClientService clientService
	
	public ProductForm() {
		// clientService is null here
	}
	
	@PostConstruct
	public postConstructor(){
		// clientService is not null here
		clientService.getAll(); // works
	}
}

Thanks for your help, now is not null anymore