16

I've been working with Spring Data with Spring Boot. With the JavaConfig documentation I have set up a Spring JPA configuration, but when calling the save method in my repository a null pointer is thrown.

My repository:

import org.springframework.data.jpa.repository.JpaRepository;

public interface HouseRepository extends JpaRepository<House, Long> {
}

My POJO's:

AbstractHouse

@MappedSuperclass
@Table(name="houses")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
public abstract class AbstractHouse implements Serializable {

@NotEmpty
private String houseName;

@NotEmpty
private String houseNumber;

House

@Entity
public class SmallHouse extends AbstractHouse {

@Id
@GeneratedValue
private Long id;

private Date created;

private Date updated;

I've then got a service object that takes an Autowired repository and attempts to save using methods obtained through JPA:

@Service
public class HouseService {

@Autowired
protected HouseRepository houseRepository;

public void save(House house) {
    houseRepository.save(house);
} 

My application class contains:

@SpringBootApplication
@EnableScheduling
@EnableJpaRepositories
public class Application {

public static void main(String[] args) throws Exception {
    SpringApplication.run(Application.class, args);
}
}

I am fairly new to Spring Data, so I do think its something within the configuration that I am missing, any advice would be greatly appreciated!

--Update--

Stack Trace:

java.lang.NullPointerException
    at com.jm.service.HouseService.save(HouseService.java:15)
    at com.jm.service.HouseClass.gatherHouses(HouseClass.java:43)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:775)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:705)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:858)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:85)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:217)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)

And I call the method as such:

public class HouseMain {

    @Autowired
    public HouseService houseService;

    public void gatherHouse() {
    houseService = new HouseService();
    House h = new House();
    h.setHouseName("House1");
    h.setHouseNumber("12");
    try {

        HouseService.save(vmComp);          
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}
}

Then in my controller I am calling house.gatherHouse

James Millner
  • 241
  • 2
  • 3
  • 11
  • Show us exact stacktrace of your exception. And how do you call your `HouseService.save` method? – Nikem May 25 '16 at 17:25
  • Edited the post now. – James Millner May 25 '16 at 17:54
  • Please, provide us with the code which at least compiles. You use `h` before you declare it, `vmComp` is undeclared... – Nikem May 25 '16 at 17:59
  • 1
    I'm not sure why you need to create the HouseService class. Therefore, I'd just remove it and make HouseMain as such: `public class HouseMain { @Autowired public HouseRepository houseRepository; public void gatherHouse() { //houseService = new HouseService(); House h = new House(); h.setHouseName("House1"); h.setHouseNumber("12"); try { //HouseService.save(vmComp); houseRepository.save(h); } } catch (Exception e) { e.printStackTrace(); } }` – mugua May 25 '16 at 18:37
  • This is a helpful link: [link](https://www.moreofless.co.uk/spring-mvc-java-autowired-component-null-repository-service/) Bottom line is use `@Autowire` instead of manual initialization. – realpac Mar 16 '18 at 17:52
  • This answer helped me solve my issue: https://stackoverflow.com/a/2302814/7769052 – banan3'14 Aug 23 '18 at 22:31

2 Answers2

21

You currently instantiate HouseService by hand, not through Spring. In the houseService object that you created you have field HouseRepository houseRepository which is null, because you don't initialize it in any way. If you use Spring and its Autowired functionality, then you should get the instance of HouseService from Spring context. E.g. you can @Autowired it into your controller class.

Nikem
  • 5,716
  • 3
  • 32
  • 59
  • This is where I think I am getting confused. I've annotated the service, which I believed set it up with the application context. If I take out the houseService = new HouseService(); the null pointer then goes onto the HouseService class, which again will be down to defining the context. – James Millner May 25 '16 at 18:08
  • No, just annotating the server does not automatically create nor start Spring context. Please consult Spring docs how to do that. – Nikem May 25 '16 at 18:15
  • After looking at: https://spring.io/guides/gs/spring-boot/ I added some code to output all the registered beans, and I can see a houseRepository & houseService bean within the applications context. So it does appear they have been registered correctly, but I cant access them within my classes? – James Millner May 25 '16 at 18:25
  • 1
    @JamesMillner You seem not to understand the difference between a Spring-managed bean and a POJO instance. Of course there are `houseRepository` and `houseService` beans. They were created within the container when the framework was starting up. But in `gatherHouse()` you have created an instance that is not managed by the framework in any way. Therefore Spring knows nothing about it and cannot autowire any dependency into it and therefore the `houseRepository` field has a `null` reference. – tkralik May 25 '16 at 18:45
  • 2
    @JamesMillner If you use Spring, then never create new instances yourself. Always ask them from Spring context. This is the simple rule that you can follow until you really understand the inner workings of Spring :) – Nikem May 25 '16 at 19:32
  • @Nikem this makes total sense now! I did some reading up on spring application context and yes, I see now where I went wrong! Thanks for the extra set of eyes! – James Millner May 26 '16 at 07:42
  • @JamesMillner you that was useful, please upvote and accept the answer :) – Nikem May 26 '16 at 07:57
5

This is not correct:

 houseService = new HouseService();

since you are using Spring , you should allow Spring to create all the beans ,that's the reason of using @Autowired, which in this case is not getting executed and houseRepository is initialised as null.

shankarsh15
  • 1,947
  • 1
  • 11
  • 16