I had Spring Data's repository working in a @Controller a short while ago. Having moved data access down into a @Service, it stopped working. Everything looks fine to me.... Why is this DI failing?
Here's my spring-config:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:data="http://www.springframework.org/schema/data/jpa"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="POSTGRESQL" />
<property name="databasePlatform" value="org.hibernate.dialect.PostgreSQLDialect" />
</bean>
<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<property name="dataSource" ref="dataSource" />
<property name="jpaDialect" ref="jpaDialect" />
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.postgresql.Driver" />
<property name="url" value="jdbc:postgresql://localhost:5432/cp" />
<property name="username" value="cp_user" />
<property name="password" value="+JMJ+pw0m2d" />
</bean>
<data:repositories base-package="com.mydomain.data.repository" />
<mvc:annotation-driven />
</beans>
My application:
@ComponentScan
@EnableAutoConfiguration
@ImportResource("classpath:spring-config.xml")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
My controller:
@Controller
@RequestMapping("/app/user")
@ExposesResourceFor(User.class)
public class UserController {
@RequestMapping(value = "/{userid}", method = RequestMethod.GET, produces = "application/json")
@ResponseBody
public HttpEntity<UserResource> get(@PathVariable("userid") long id) {
ProfileService ps = new ProfileService();
UserResource resource = ps.get(id);
return new ResponseEntity<UserResource>(resource, HttpStatus.OK);
}
}
And my service:
@Service
@ExposesResourceFor(User.class)
public class ProfileService {
@Inject
private UserRepository users;
public UserResource get(long id) {
Long longId = new Long(id);
User user = users.findOne(longId); // Line 24
if (user == null) {
throw new ResourceNotFoundException();
}
UserMapper assembler = new UserMapper();
UserResource resource = assembler.toResource(user);
return resource;
}
public void update(UserResource resource) {
UserMapper assembler = new UserMapper();
User user = assembler.toEntity(resource);
users.save(user);
}
}
Throwing exception:
java.lang.NullPointerException
com.mydomain.service.ProfileService.get(ProfileService.java:24)
com.mydomain.app.web.UserController.get(UserController.java:74)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
java.lang.reflect.Method.invoke(Unknown Source)
org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:214)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:748)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:947)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:878)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:946)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:837)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:822)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
Where ProfileService:24 is:
User user = users.findOne(longId);
In your controller you create ProfileService
instance with a new
keyword and it is not managed by Spring (Spring doesn't know about it and cannot inject UserRepository
- this causes NullPointerException). You have to inject ProfileService
into UserController
the same way you inject UserRepository
into ProfileService
. For example:
@Controller
@RequestMapping("/app/user")
@ExposesResourceFor(User.class)
public class UserController {
@Autowired
private ProfileService profileService;
@RequestMapping(value = "/{userid}", method = RequestMethod.GET, produces = "application/json")
@ResponseBody
public HttpEntity<UserResource> get(@PathVariable("userid") long id) {
UserResource resource = profileService.get(id);
return new ResponseEntity<UserResource>(resource, HttpStatus.OK);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With