applicationContext.xml
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p" xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<context:annotation-config />
<context:component-scan base-package="com.company" />
<!-- 定义实体管理器工厂 -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="eipjpa" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<jpa:repositories base-package="com.company.repository" />
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="eipjpa" transaction-type="RESOURCE_LOCAL">
<provider>
org.apache.openjpa.persistence.PersistenceProviderImpl
</provider>
<class>com.company.domain.User</class>
<properties>
<property name="openjpa.ConnectionURL" value="jdbc:mysql://localhost:3306/eipdb?characterEncoding=utf-8" />
<property name="openjpa.ConnectionUserName" value="root" />
<property name="openjpa.ConnectionPassword" value="passw0rd" />
<property name="openjpa.Log" value="DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE" />
<property name="openjpa.DynamicEnhancementAgent" value="true"/>
</properties>
</persistence-unit>
</persistence>
Domain Class - User (omit constructor, get, set)
@Entity
@Table(name = "user")
public class User implements java.io.Serializable{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
private String username;
private String password;
private String type;
}
Repository interface
@Repository
public interface UserRepository extends CrudRepository<User, Integer> {
List<User> findUserByUsernameAndPassword(String username, String password);
}
UserService Interface
public interface UserService {
void saveUser(User user);
User findUserById(Integer id);
void updateUser(User user);
void deleteUserById(Integer id);
public boolean checkUserLogin(User user);
}
Implementation of UserService
@Service("userService")
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
@Override
@Transactional
public void saveUser(User user) {
userRepository.save(user);
}
@Override
@Transactional(readOnly = true)
public User findUserById(Integer id) {
return userRepository.findOne(id);
}
@Override
@Transactional
public void updateUser(User user) {
userRepository.save(user);
}
@Override
@Transactional
public void deleteUserById(Integer id) {
userRepository.delete(id);
}
@Override
@Transactional(readOnly = true)
public boolean checkUserLogin(User user) {
System.out.println(userRepository);
return userRepository.findUserByUsernameAndPassword(user.getUsername(), user.getPassword()).size() == 0 ? false
: true;
}
Problem
When I test it by junit, it works fine.
@Test
public void login() {
User user = new User();
user.setUsername("Annie");
user.setPassword("passw0rd");
UserService service = ctx.getBean(UserService.class);
Assert.assertTrue(service.checkUserLogin(user));
user.setPassword("password");
Assert.assertFalse(service.checkUserLogin(user));
}
But when I try it in webapp, below error occurred... I checked that the userRepository in UserServiceImpl class is null... I don't know how to fix it...
Feb 19, 2014 12:25:53 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/EIP] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException
at com.company.service.impl.UserServiceImpl.checkUserLogin(UserServiceImpl.java:53)
at com.company.controller.UserController.login(UserController.java:30)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:436)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:424)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:409)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1044)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:313)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:695)
Spring will never leave an injection target like this one
@Autowired
private UserRepository userRepository;
null
. If it can't resolve the dependency it will throw all sorts of exceptions.
In other words, in your web application, Spring must not be involved in creating your UserServiceImpl
object. I'm going to guess you are creating it yourself with new
. You should instead be injecting it with @Autowired
or at least getting it from the ApplicationContext
directly (bad practice).
In your test case however, you are clearly getting the instance from the ApplicationContext
, so it is a managed bean and its dependencies have been resolved.