Spring Data JPA repository throws null pointer
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
.
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, 2020Comments
-
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 almost 8 yearsThis 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 almost 8 yearsNo, just annotating the server does not automatically create nor start Spring context. Please consult Spring docs how to do that.
-
James Millner almost 8 yearsAfter 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 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
andhouseService
beans. They were created within the container when the framework was starting up. But ingatherHouse()
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 thehouseRepository
field has anull
reference. -
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 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 almost 8 years@JamesMillner you that was useful, please upvote and accept the answer :)