Spring Data JPA repository throws null pointer

56,569

Solution 1

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.

Solution 2

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.

Share:
56,569
James Millner
Author by

James Millner

Currently studying MEng Software Engineering at the University of Huddersfield. Skills: • Java Programming. • MySQL. • PHP. • C++ (Currently Studying). • UNIX Commands. • Eclipse and Eclipse CDT. • Android Development. • Visual Studio Skills. • Adobe Flash, Fireworks and Photoshop. • Microsoft Office.

Updated on May 26, 2020

Comments

  • James Millner
    James Millner almost 4 years

    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
    James Millner almost 8 years
    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.
  • Nikem
    Nikem almost 8 years
    No, just annotating the server does not automatically create nor start Spring context. Please consult Spring docs how to do that.
  • James Millner
    James Millner almost 8 years
    After looking at: 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?
  • Tomas Kralik
    Tomas Kralik almost 8 years
    @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.
  • Nikem
    Nikem almost 8 years
    @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 :)
  • James Millner
    James Millner almost 8 years
    @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!
  • Nikem
    Nikem almost 8 years
    @JamesMillner you that was useful, please upvote and accept the answer :)