I am very new to Spring+Hibernate and am working on a very basic web project. Simple form is used and has two fields username and password. It has a submit button. When clicking on submit I am supposed to check if username and password exists in the database or not.This is my AuthenticationService Class
package com.service;
import java.util.List;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Service;
#Service
public class AuthenticateService{
private HibernateTemplate hibernateTemplate;
public void setSessionFactory(SessionFactory sessionFactory)
{
this.hibernateTemplate=new HibernateTemplate(sessionFactory);
}
public boolean verifyUsernameAndPassword(String username,String password)
{
System.out.println("Into the Service Class");
boolean userStatus=false;
try
{
List userObj = hibernateTemplate.find("from user u where u.username=? and u.password=?",username,password);
if(userObj.size()!=0)
{
userStatus=true;
}
}
catch(Exception e)
{
e.printStackTrace();
}
return userStatus;
}
}
This is my bean configuration file:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dataSourceBean" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/springmvc"></property>
<property name="username" value="root"></property>
<property name="password" value=""></property>
</bean>
<!-- org.springframework.orm.hibernate3.LocalSessionFactoryBean -->
<bean id="sessionFactoryBean" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSourceBean"></property>
<property name="mappingResources">
<value>com/pojo/user.hbm.xml</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="hibernateTemplateBean" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactoryBean"></property>
</bean>
<bean id="authenticateServiceBean" class="com.service.AuthenticateService">
<property name="hibernateTemplate" ref="hibernateTemplateBean"></property>
</bean>
</beans>
This is my Login Controller:
package com.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import com.service.AuthenticateService;
#Controller
#RequestMapping("/login.spring")
public class LoginController {
#Autowired
AuthenticateService authenticateService;
#RequestMapping(method= RequestMethod.POST)
public ModelAndView processCredentials(#RequestParam("username")String username ,#RequestParam("password")String password)
{
System.out.println("Inside username"+username + " password"+password);
String message="Invalid Credentials";
if(authenticateService.verifyUsernameAndPassword(username, password)==true)
{
message="Welcome"+username;
}
return new ModelAndView("results","message",message);
}
}
When I run the application I get the following stacktrace :
java.lang.NullPointerException
at com.service.AuthenticateService.verifyUsernameAndPassword(AuthenticateService.java:31)
at com.controller.LoginController.processCredentials(LoginController.java:26)
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:440)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:428)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:838)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:861)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:606)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:662)
I am sure the application goes to the Service class as I have printed the "Inside the Service Class". I don't know why its giving me a NullPointer.
You have two beans of type "com.service.AuthenticateService" one via annotation another in xml file.
The one defined via annotation is not provided hibernate template reference, hence null.
The one defined in xml is having proper reference but is not the one that gets injected.
Hope this helps.
Related
I am trying to implement a signup page using Spring MVC integrated with hibernate using XML.
Application Context.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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
xmlns:tx="http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>
<property name="url" value="jdbc:oracle:thin:#localhost:1521:xe"></property>
<property name="username" value="hr"></property>
<property name="password" value="umashetti123"></property>
</bean>
<bean id="mysessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="mappingResources">
<list>
<value>Login_Detailshbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="checkWriteOperation" >false</prop>
</props>
</property>
</bean>
<bean id="template" class="org.springframework.orm.hibernate5.HibernateTemplate">
<property name="sessionFactory" ref="mysessionFactory"></property>
<property name="checkWriteOperations" value="false"></property>
</bean>
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="mysessionFactory" />
</bean>
<bean id="d" class="com.uday.Login_DetailsDao">
<property name="template" ref="template"></property>
</bean>
</beans>
Controller Class
package com.uday;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
#Controller
public class ControllerSignUp_Login {
public ControllerSignUp_Login() {
// TODO Auto-generated constructor stub
}
#RequestMapping("/hello")
public String diaplay(#RequestParam("name") String name, #RequestParam("pass") String pass,Model m) {
Login_DetailsDao dao = (Login_DetailsDao) getBean();
if(dao.isLogoinSuccessfull(name , pass)) {
m.addAttribute("message", "Hello"+name);
return "Success";
}
else {
m.addAttribute("message", "You have Entered Wrong pin");
return "Failure";
}
}
#RequestMapping("/SignUp")
public String redirect() {
System.out.println("ControllerSignUp_Login.display()");
return "signup";
}
#RequestMapping("/login")
public String display() {
System.out.println("ControllerSignUp_Login.display()");
return "login";
}
#RequestMapping("/updateDetails")
#Transactional
public String display(HttpServletRequest req , Model M) {
String firstName=req.getParameter("firstName");
String lastName=req.getParameter("lastName");
String mobileNo=req.getParameter("mobileNo");
String address=req.getParameter("address");
String city=req.getParameter("city");
String password=req.getParameter("password");
Login_DetailsDao dao = (Login_DetailsDao) getBean();
if(checkLength(firstName) && checkLength(lastName) && checkLength(mobileNo) && checkLength(address) && checkLength(city) && checkLength(password)) {
Login_Details ld = new Login_Details();
ld.setFirstName(firstName);
ld.setLastName(lastName);
ld.setCity(city);
ld.setAddress(address);
ld.setMobileNo(mobileNo);
ld.setPassword(password);
dao.saveEmployee(ld);
M.addAttribute("message", "SignUp Successfull !! Thank You");
M.addAttribute("displayLogin", true);
return "Success";
}
else {
M.addAttribute("message","SignUp Failed !! All details are mandatory.");
return "signup";
}
}
public boolean checkLength(String s) {
if(s != null && s.length() > 0) {
return true;
}
return false;
}
public Object getBean() {
ApplicationContext appcontext = new ClassPathXmlApplicationContext("Applicationcontext.xml");
Login_DetailsDao lDDao =(Login_DetailsDao)appcontext.getBean("d");
return lDDao;
}
}
DAO class
package com.uday;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.orm.hibernate5.HibernateTemplate;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.transaction.annotation.Transactional;
public class Login_DetailsDao {
HibernateTemplate template;
HibernateTransactionManager hbt;
public HibernateTransactionManager getHbt() {
return hbt;
}
public void setHbt(HibernateTransactionManager hbt) {
this.hbt = hbt;
}
public Login_DetailsDao() {
// TODO Auto-generated constructor stub
}
#Transactional
public void saveEmployee(Login_Details e){
System.out.println("Login_DetailsDao.saveEmployee()"+e.getMobileNo());
SessionFactory sf = hbt.getSessionFactory();
Session session =sf.getCurrentSession();
Transaction t =session.beginTransaction();
session.persist(e);
t.commit();
session.close();
}
public void setTemplate(HibernateTemplate template) {
this.template = template;
}
public List<Login_Details> getEmployees(){
List<Login_Details> list=new ArrayList<Login_Details>();
list=template.loadAll(Login_Details.class);
return list;
}
}
I am able to get the login_details data but unable to insert the record.
getting below exception
org.xml.sax.SAXParseException; lineNumber: 51; columnNumber: 29; cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'tx:annotation-driven'.
Could any one please suggest to solve this?
Your code is flawed on multiple levels.
Never create a BeanFactory or ApplicationContext just because you need an instance of a bean. Instead use dependency injecting for that bean.
The fact that you use a BeanFactory over an ApplicationContext is one of the reasons your code doesn't work. See this for why you shouldn't use a BeanFactory.
You aren't using transactions and without transactions nothing will be persisted in the database.
Now first in your controller you need to dependency inject the Login_DetailsDao instead of creating a BeanFactory and obtain an instance.
#Controller
public class ControllerSignUp_Login {
private final Login_DetailsDao dao;
#Autowired // If using Spring 4.3 or later this isn't needed
public ControllerSignUp_Login(Login_DetailsDao dao) {
this.dao=dao;
}
}
Now in your method use this instance, instead of doing the lookup.
Your Login_DetailsDao should operate on the SessionFactory and nothing else.
public class Login_DetailsDao {
private final SessionFactory sf;
public Login_DetailsDao(SessionFactory sf) {\
this.sf=sf;
}
#Transactional
public void saveEmployee(Login_Details e){
sf.getCurrentSession().save(e);
}
#Transactional(readOnly=true)
public List<Login_Details> getEmployees(){
return sf.getCurrentSession()
.createQuery("SELECT ld FROM Login_Details", Login_Details.class)
.getResult();
}
}
That is all you need. Now finally in your XML tie all this together.
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"
xmlns:tx="http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<tx:annotation-driven />
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>
<property name="url" value="jdbc:oracle:thin:#localhost:1521:xe"></property>
<property name="username" value="hr"></property>
<property name="password" value="umashetti123"></property>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="mappingResources">
<list>
<value>Login_Detailshbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="checkWriteOperation" >false</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="d" class="com.uday.Login_DetailsDao">
<constructor-arg ref="sessionFactory" />
</bean>
</beans>
One simple change made this application worked.
1 > Deleted applicationcontext.xml and added the contents in disapatcher-servlet.xml
disaptcher-servlet.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:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
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/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<context:annotation-config/>
<tx:annotation-driven />
<!-- Provide support for component scanning -->
<context:component-scan base-package="com.uday" />
<!--Provide support for conversion, formatting and validation -->
<mvc:annotation-driven/>
<!-- Define Spring MVC view resolver -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/page/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>
<property name="url" value="jdbc:oracle:thin:#localhost:1521:xe"></property>
<property name="username" value="hr"></property>
<property name="password" value="umashetti123"></property>
</bean>
<bean id="mysessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="mappingResources">
<list>
<value>Login_Detailshbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="checkWriteOperation" >false</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="mysessionFactory" />
</bean>
<bean id="d" class="com.uday.Login_DetailsDao">
<constructor-arg ref="mysessionFactory" />
</bean>
</beans>
DAO Class:
package com.uday;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.springframework.transaction.annotation.Transactional;
public class Login_DetailsDao {
private final SessionFactory sessionFactory;
public Login_DetailsDao(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
#Transactional
public void saveEmployee(Login_Details e){
sessionFactory.getCurrentSession().save(e);
}
public boolean isLogoinSuccessfull(String uName , String password) {
List<Login_Details> a= getEmployees();
Iterator<Login_Details> i = a.iterator();
while(i.hasNext()) {
Login_Details ld = i.next();
String mobileNo = ld.getMobileNo();
String pas = ld.getPassword();
if(mobileNo != null && mobileNo.equals(uName) && pas != null && pas.equals(password)) {
return true;
}
}
return false;
}
#Transactional
public List<Login_Details> getEmployees(){
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Login_Details.class);
List<Login_Details> l = criteria.list();
return l;
}
}
Controller Class:
package com.uday;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
#Controller
public class ControllerSignUp_Login {
#Autowired
private final Login_DetailsDao dao;
#Autowired
public ControllerSignUp_Login(Login_DetailsDao login_DetailsDao) {
this.dao = login_DetailsDao;
}
#RequestMapping("/hello")
#Transactional
public String diaplay(#RequestParam("name") String name, #RequestParam("pass") String pass,Model m) {
if(dao.isLogoinSuccessfull(name , pass)) {
m.addAttribute("message", "Hello"+name);
return "Success";
}
else {
m.addAttribute("message", "You have Entered Wrong pin");
return "Failure";
}
}
#RequestMapping("/SignUp")
public String redirect() {
System.out.println("ControllerSignUp_Login.display()");
return "signup";
}
#RequestMapping("/login")
public String display() {
System.out.println("ControllerSignUp_Login.display()");
return "login";
}
#RequestMapping("/updateDetails")
#Transactional
public String display(HttpServletRequest req , Model M) {
String firstName=req.getParameter("firstName");
String lastName=req.getParameter("lastName");
String mobileNo=req.getParameter("mobileNo");
String address=req.getParameter("address");
String city=req.getParameter("city");
String password=req.getParameter("password");
if(checkLength(firstName) && checkLength(lastName) && checkLength(mobileNo) && checkLength(address) && checkLength(city) && checkLength(password)) {
Login_Details ld = new Login_Details();
ld.setFirstName(firstName);
ld.setLastName(lastName);
ld.setCity(city);
ld.setAddress(address);
ld.setMobileNo(mobileNo);
ld.setPassword(password);
dao.saveEmployee(ld);
M.addAttribute("message", "SignUp Successfull !! Thank You");
M.addAttribute("displayLogin", true);
return "Success";
}
else {
M.addAttribute("message","SignUp Failed !! All details are mandatory.");
return "signup";
}
}
public boolean checkLength(String s) {
if(s != null && s.length() > 0) {
return true;
}
return false;
}
}
Project Structure looks like below
Instead of getting current session and making the transaction opened new session that's it worked like charm!!!
I don't know why it is not working if I am getting current session!!
#Transactional
public void saveEmployee(Login_Details e){
System.out.println("Login_DetailsDao.saveEmployee()"+e.getMobileNo());
SessionFactory sf = hbt.getSessionFactory();
//Changed here
Session session =sf.openSession(); //Session session =sf.getCurrentSession();
Transaction t =session.beginTransaction();
session.persist(e);
t.commit();
session.close();
}
I have been working on various issues to get this Spring-Hibernate app to work. I have probably made a basic error.
This seems to be a recurring question with many answers covering older versions of Hibernate. I am using Spring 4.3.9 and Hibernate 4.0.5
The UT gets a SessionFactory but getCurrentSession() is returning null and in debug I can see that currentSessionContext is null.
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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="data.xml"/>
</beans>
data.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
>
<!-- Enable autowiring -->
<tx:annotation-driven/>
<!-- context:annotation-config/-->
<bean id="myDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource"/>
<property name="packagesToScan" value="com.my"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.connection.pool-size">1</prop>
<prop key="hibernate.cache.provider_cache">org.hibernate.cache.NoCacheProvider</prop>
<prop key="show_sql">true</prop>
<prop key="hibernate.current_session_context_class">thread</prop>
</props>
</property>
</bean>
</beans>
SpringConfig.java
package utils.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportResource;
#Configuration
#Import
(
{SpringRepositoryConfig.class
}
)
#ImportResource("classpath:configuration/applicationContext.xml")
public class SpringConfig
{
}
SpringRepositoryConfig.java
package utils.config;
import org.hibernate.SessionFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import utils.persistence.ItemRepository;
import utils.persistence.HibernateItemRepositoryImpl;
import org.springframework.beans.factory.annotation.Autowired;
// Declare as a configuration class
#Configuration
public class SpringRepositoryConfig
{
#Autowired
SessionFactory sessionFactory;
// Define repository bean
#Bean
public ItemRepository itemRepository()
{
ItemRepository rep = new HibernateItemRepositoryImpl();
rep.setSessionFactory(sessionFactory);
return rep;
}
}
SpringServicesConfig.java
package utils.config;
import javax.inject.Inject;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import bussysutils.persistence.ItemRepository;
import bussysutils.repository.DecoderLoadRepository;
import bussysutils.repository.DecoderLoadRepositoryImpl;
#Configuration
public class SpringServicesConfig
{
#Inject
ItemRepository repository;
#Bean
public DecoderLoadRepository decoderLoadRepository()
{
DecoderLoadRepositoryImpl decoderLoad = new DecoderLoadRepositoryImpl(repository);
return decoderLoad;
}
}
SessionConfig.java
package utils;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
public class SessionConfig
{
public static SessionFactory buildFactory(String url
,String user
,String password)
{
ServiceRegistry sr;
SessionFactory sfactory;
Configuration config = new Configuration();
config.setProperty("hibernate.connection.url", url);
config.setProperty("hibernate.connection.username", user);
config.setProperty("hibernate.connection.password", password);
StandardServiceRegistryBuilder ssrb
= new StandardServiceRegistryBuilder().applySettings(config.getProperties());
sr = ssrb.build();
try
{
sfactory = config.buildSessionFactory(sr);
}
catch (Throwable ex)
{
throw new ExceptionInInitializerError(ex);
}
return sfactory;
}
}
UT_DecoderLoad.java
import org.hibernate.SessionFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import utils.DecoderLoad;
import utils.SessionConfig;
import utils.config.SpringConfig;
import utils.persistence.HibernateItemRepositoryImpl;
import utils.persistence.ItemRepository;
import java.sql.DriverManager;
import java.sql.SQLException;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
#ContextConfiguration(classes = SpringConfig.class)
#RunWith(SpringJUnit4ClassRunner.class)
public class UT_DecoderLoad
{
#Autowired
SessionFactory sessionFactory;
#Test
public void decoderLoadTest()
{
try
{
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
sessionFactory = SessionConfig.buildFactory("jdbc:oracle:thin:#(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=my-host-name.my.com)(PORT=1521))(CONNECT_DATA=(SERVER=dedicated)(SERVICE_NAME=dev)))"
,"myuser"
,"mypassword");
}
catch (SQLException e)
{
System.err.println("uploadServlet ERROR - " + e.getMessage());
System.out.print("uploadServlet logon ERROR - SQLException: " + e.getMessage());
e.printStackTrace();
}
Session s = sessionFactory.getCurrentSession(); /// <<<<<<<<
s.beginTransaction();
DecoderLoad decoderLd = new DecoderLoad();
decoderLd.setSiteRefNo("123456");
System.out.println(decoderLd.getSiteRefNo());
// update the database
ItemRepository itemRepo = new HibernateItemRepositoryImpl();
// itemRepo.create(decoderLd);
s.save(decoderLd);
s.getTransaction().commit();
}
}
You are making things very complicated for yourself, first you are mixing XML and Java based configuration and you have a configuration class for single beans. Either use Java or XML but don't mix them, especially if you aren't sure what those things do.
Your DataSource setup is also flawed as it is a partially setup DataSource.
Next your SessionFactory configuration is basically useless due to the use of the SessionConfig (which basically renders your Spring configuration useless). You shouldn't be using the SessionConfig, so drop it. Your SessionFactory configuration in the XML is also flawed, the hibernate.connection properties don't do anything, due the the injected DataSource and you shouldn't be messing around with the hibernate.current_session_context property unless you are using JTA. Spring will manage it for you.
Your unit test is also flawed, you should be injecting the repository not creating a new instance yourself.
That being said and moving everything to xml your data.xml should look something like this.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd"
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context">
<tx:annotation-driven/>
<context:property-placeholder location="jdbc.properties" />
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="com.my"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.cache.provider_cache">org.hibernate.cache.NoCacheProvider</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernatTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="itemRepository" class="utils.config.HibernateItemRepositoryImpl">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="decoderLoadRepository" class="utils.config.DecoderLoadRepositoryImpl">
<constructor-arg ref="itemRepository" />
</bean>
</beans>
The jdbc.properties would contain the following
jdbc.url=jdbc:oracle:thin:#(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=my-host-name.my.com)(PORT=1521))(CONNECT_DATA=(SERVER=dedicated)(SERVICE_NAME=dev)))
jdbc.username=myuser
jdbc.password=mypassword
You can now drop your SessionConfig, SpringServicesConfig and SpringRepositoryConfig classes as the first you shouldn't have in the first place the config class are obsolete due to adding the context to the xml file.
Now your test is also flawed as it should be #Transactional and should load the XML file instead of the java config.
#ContextConfiguration("classpath:configuration/applicationContext.xml")
#RunWith(SpringJUnit4ClassRunner.class)
#Transactional
public class UT_DecoderLoad {
#Autowired
SessionFactory sessionFactory;
#Test
public void decoderLoadTest() {
Session s = sessionFactory.getCurrentSession(); /// <<<<<<<<
DecoderLoad decoderLd = new DecoderLoad();
decoderLd.setSiteRefNo("123456");
System.out.println(decoderLd.getSiteRefNo());
s.save(decoderLd);
s.flush(); // "simulate a commit"
}
}
Although not sure what you are testing here, you should probably be testing the HibernateItemRepositoryImpl.
#ContextConfiguration("classpath:configuration/applicationContext.xml")
#RunWith(SpringJUnit4ClassRunner.class)
#Transactional
public class UT_DecoderLoad {
#Autowired
SessionFactory sessionFactory;
#Autowired
ItemRepository repository
#Test
public void decoderLoadTest() {
DecoderLoad decoderLd = new DecoderLoad();
decoderLd.setSiteRefNo("123456");
repository.create(decoderLd);
sessionFactory.getCurrentSession().flush(); // "simulate a commit"
// Validate the existence in the database
}
}
This is my current version, it runs but does not update the db table.
data.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
>
<!-- Enable autowiring -->
<tx:annotation-driven/>
<context:property-placeholder location="resources/jdbc.properties"/>
<bean id="DataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="DataSource"/>
<property name="packagesToScan" value="utils"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.cache.provider_cache">org.hibernate.cache.NoCacheProvider</prop>
<prop key="show_sql">true</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="itemRepository" class="utils.persistence.HibernateItemRepositoryImpl">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="decoderLoadRepository" class="utils.repository.DecoderLoadRepositoryImpl">
<constructor-arg ref="itemRepository" />
</bean>
</beans>
UT_DecoderLoad.java
import org.hibernate.SessionFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import utils.DecoderLoad;
import utils.persistence.ItemRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
#ContextConfiguration("classpath:configuration/applicationContext.xml")
#RunWith(SpringJUnit4ClassRunner.class)
#Transactional
public class UT_DecoderLoad
{
#Autowired
SessionFactory sessionFactory;
#Autowired
ItemRepository itemRepo;
#Test
public void decoderLoadTest()
{
DecoderLoad decoderLd = new DecoderLoad();
decoderLd.setSiteRefNo("123456");
decoderLd.setDecoderNo("999");
System.out.println(decoderLd.getSiteRefNo());
itemRepo.create(decoderLd);
sessionFactory.getCurrentSession().flush();
}
}
I added a primary key column into the db table so that I could add the required #Id
DecoderLoad.java
package utils;
import javax.persistence.*;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
#Entity
#Table(name = "Decoder_Load")
public class DecoderLoad
{
public DecoderLoad()
{
}
// pojo with annotations
#Id
#Column(name = "decoder_no")
private String decoderNo;
...
I also added javassist to the pom.
Maven compile complains:
package org.springframework.test.context does not exist
package org.springframework.test.context.junit4 does not exist
This simple test runs but it is not inserting a record without forcing it and causing other issues.
EDIT: just learned that a test does a rollback so it will not commit.
I am new to Spring & Hibernate and I have spent a couple of weeks trying to get to grips with it. Most of my experience is with Oracle development so this is a departure for me. Hibernate is working but Spring is giving me a headache.
I tried following this tutorial but using an Oracle db and my Address table.
http://www.codejava.net/frameworks/spring/spring-4-and-hibernate-4-integration-tutorial-part-1-xml-configuration
The web page wasn't working so I tried a test case on the HomeController.java That didn't work so but I believe I have narrowed it down to a null pointer in addressDao and so I wrote a test case for that to try to pin it down.
java.lang.NullPointerException: null
springexp.unittest.AddressDaoTest.testListAddr(AddressDaoTest.java:29)
package springexp.unittest;
import bussys.model.Address;
import springexp.dao.AddressDao;
import java.util.List;
import static org.junit.Assert.*;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
public class AddressDaoTest
{
#Autowired
private AddressDao addressDao;
#RequestMapping(value="/")
/**
* #see springexp.dao.AddressDao#listAddr()
*/
#Test
public void testListAddr()
{
List<Address> listAddresses = addressDao.listAddr(); << error thrown here
System.out.println(listAddresses.get(1).getFirstname());
fail("Unimplemented");
}
}
I have also spent a long time reading stackoverflow and others to try to fix the null pointer issue but there seems to be lots of ways of writing this and it has changed in various versions.
In servlet-context.xml I have this:
<!-- Hibernate Session Factory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>springexp.dao.AddressDao</value>
</list>
</property>
</bean>
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="addressDao" class="springexp.dao.AddressDaoImpl">
<constructor-arg>
<ref bean="sessionFactory" />
</constructor-arg>
</bean>
<!-- added this recently based on one suggestion -->
<bean id="addressDaoTest" class="springexp.unittest.AddressDaoTest">
<constructor-arg>
<ref bean="sessionFactory" />
</constructor-arg>
</bean>
AddressDaoImpl.java
package springexp.dao;
import bussys.model.Address;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.springframework.transaction.annotation.Transactional;
public class AddressDaoImpl
implements AddressDao
{
private SessionFactory sessionFactory;
public AddressDaoImpl(SessionFactory sessionFactory)
{
this.sessionFactory = sessionFactory;
}
#Override
#Transactional
public List<Address> listAddr()
{
#SuppressWarnings("unchecked")
List<Address> listAddress = (List<Address>)
sessionFactory.getCurrentSession().createCriteria(Address.class).setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).list();
return listAddress;
}
}
I hope this is enough to give a clue to my mistake(s).
I am having difficulties while trying to launch my application, I am stuck somewhere in the code.
my entity class is:
#Entity
#Table(name="metalocation")
public class Location implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="ID")
private int id;
#Column(name="DB_ID")
private String dbId;
#Column(name="GEO_LAT")
private double geoLAT;
#Column(name="GEO_LNG")
private double geoLNG;
#Column(name="IN_LOCATION")
private int inLocation;
#Column(name="ISO")
private String iso;
#Column(name="LOCAL_NAME")
private String localName;
#Column(name="TYPE")
private char type;
#OneToMany(cascade=CascadeType.PERSIST)
#JoinColumn(name="meta_address_fk")
private Set<Address> address;
public Location() {
}
.......... All setters and getters
my Service interface is:
import java.util.List;
import com.platformhouse.clinicsystem.web.model.entity.Address;
import com.platformhouse.clinicsystem.web.model.entity.Location;
public interface AddressService {
public List<Location> getAllCountries();
}
my service class is:
#Service("adressService")
#Transactional
public class AddressServiceImplementation implements AddressService {
private AddressDAO addressDAO;
//
public void setPatientDao(AddressDAO addressDAO) {
this.addressDAO = addressDAO;
}
#Transactional
public List<Location> getAllCountries() {
return this.addressDAO.getAllCountries();
}
}
My DAO is:
#Repository
#Transactional
public class AddressDAO {
#Autowired
private SessionFactory session;
public void setSession(SessionFactory session) {
this.session = session;
}
public Session session(){
return session.getCurrentSession();
}
#SuppressWarnings("unchecked")
public List<Location> getAllCountries() {
Query query = session().createQuery("from Location where inLocation <=246");
List<Location> results = query.list();
return results;
}
}
my Controller is:
#Controller
#RequestMapping(value = "/usersignup")
public class PatientSignupController {
private PatientService patientService;
private AddressService addressService;
#RequestMapping(value = "/usersignup")
public String signup() {
return "usersignup";
}
#RequestMapping( method = RequestMethod.GET)
public List<Location> getCountries() {
return this.addressService.getAllCountries();
}
}
my hibernate xml:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mydb" />
<property name="username" value="username" />
<property name="password" value="password" />
</bean>
<context:component-scan base-package="com.platformhouse.clinicsystem.web.dao">
</context:component-scan>
<!-- Hibernate 4 SessionFactory Bean definition -->
<bean id="hibernate4AnnotatedSessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.platformhouse.clinicsystem.web.model.entity.User</value>
<value>com.platformhouse.clinicsystem.web.model.entity.UserType</value>
</value>
<value>com.platformhouse.clinicsystem.web.model.entity.Location
</value>
<
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect
</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="javax.persistence.validation.group.pre-persist">com.platformhouse.clinicsystem.web.validation.PersistenceValidationGroup
</prop>
<prop key="javax.persistence.validation.group.pre-update">com.platformhouse.clinicsystem.web.validation.PersistenceValidationGroup
</prop>
<prop key="javax.persistence.validation.group.pre-remove">com.platformhouse.clinicsystem.web.validation.PersistenceValidationGroup
</prop>
</props>
</property>
<property name="packagesToScan">
<list>
<value>com.platformhouse.clinicsystem.web.dao</value>
<value>com.platformhouse.clinicsystem.web.service.implementation</value>
</list>
</property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="exceptionTranslator"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor">
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory" />
</bean>
my JSp code is:
<form method="Get">
<label>Country/region:</label>
<select id="iCountry" name="iCountry">
<c:forEach items="${locationList}" var="country">
<option selected="selected" value="">please select country</option>
<option value="${country.id}">${country.localName}</option>
</c:forEach>
<select />
my results are:
HTTP Status 500 - Request processing failed; nested exception is java.lang.NullPointerException
**type Exception report
message Request processing failed; nested exception is java.lang.NullPointerException
description The server encountered an internal error that prevented it from fulfilling this request.
exception
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:978)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
root cause
java.lang.NullPointerException
----------
// controller error
com.platformhouse.clinicsystem.web.controller.PatientSignupController.getCountries(PatientSignupController.java:40)
----------
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.doInvoke(InvocableHandlerMethod.java:221)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:777)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:706)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
You have forgot to add #Autowired annotation for your services. Thats why you are getting NullPointerException. Please check below
#Autowired
private PatientService patientService;
#Autowired
private AddressService addressService;
Update
You have mentioned it as #Service("adressService"). addressService is not spelled correctly.
change it to #Service("addressService")
I am trying to send a register confirmation email in my spring MVC web application and Tomcat 7 using JavaMailSender but it always returns a NullPointerException. Can anyone help me find out why I get the null pointer? Below are my config settings:
web.xml
<!-- jndi mail session -->
<resource-ref>
<description>
Resource reference to a factory for javax.mail.Session
instances that may be used for sending electronic mail
messages, preconfigured to connect to the appropriate
SMTP server.
</description>
<res-ref-name>mail/Session</res-ref-name>
<res-type>javax.mail.Session</res-type>
<res-auth>Container</res-auth>
</resource-ref>
application-servlet.xml
<!-- Mail Sender bean definition -->
<bean id="smtpSession" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/mail/session"/>
</bean>
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="session" ref="smtpSession"/>
<!--
<property name="host" value="smtp.gmail.com" />
<property name="port" value="465" />
<property name="username" value="abc#gmail.com" />
<property name="password" value="test123" />
<property name="protocol" value="smtp" />
<property name="defaultEncoding" value="UTF-8"/>
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.auth">true</prop>
<prop key="mail.smtp.connectiontimeout">5000</prop>
<prop key="mail.smtp.sendpartial">true</prop>
<prop key="mail.smtp.userset">true</prop>
<prop key="mail.mime.charset">UTF-8</prop>
<prop key="mail.smtp.isSecure">true</prop>
<prop key="mail.smtp.requiresAuthentication">true</prop>
<prop key="mail.smtp.auth">true</prop>
<prop key="mail.smtp.port">465</prop>
<prop key="mail.smtp.socketFactory.class">javax.net.ssl.SSLSocketFactory</prop>
<prop key="mail.smtp.socketFactory.fallback">false</prop>
<prop key="mail.smtp.starttls.enable">true</prop>
<prop key="mail.debug">true</prop>
</props>
</property>
-->
</bean>
<bean id="simpleMailMessage" class="org.springframework.mail.SimpleMailMessage">
<property name="from" value="abc#hotmail.com"/>
</bean>
context.xml (in tomcat conf folder)
<Context path="/MVC" docBase="MVC" debug="5" crossContext="false">
<Resource name="mail/session"
auth="Container"
type="javax.mail.Session"
username="abc#gmail.com"
password="test23"
mail.debug="true"
mail.user="abc#gmail.com"
mail.password="test123"
mail.transport.protocol="smtp"
mail.smtp.host="smtp.gmail.com"
mail.smtp.auth="true"
mail.smtp.port="25"
mail.smtp.starttls.enable="true"
/>
SendMail.java
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.MailException;
import org.springframework.mail.MailParseException;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.mail.javamail.MimeMessagePreparator;
import org.springframework.stereotype.Service;
import com.wbkit.mvc.domain.User;
#Service
public class SendMail
{
#Autowired
private JavaMailSender mailSender;
#Autowired
private SimpleMailMessage simpleMailMessage;
public void confirmRegistrationMail(User user)
{
MimeMessage message = mailSender.createMimeMessage();
try
{
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(simpleMailMessage.getFrom());
helper.setTo(user.getEmail());
helper.setSubject("MVC Registration");
helper.setText("Hello " + user.getFirstName() + " "
+ user.getLastName() + ", \n" +
" Your MVC Account Registration was successful. Your user ID is "
+ user.getEmail() + " and your password is "
+ user.getUserPass() + ".\n" +
"You can now access the mobile applicatoin or the web application "
+ " your user name (email) and password.");
}
catch (MessagingException e)
{
throw new MailParseException(e);
}
mailSender.send(message);
}
public void requireApprovalMail(final User user)
{
}
}
Stack Trace:
4-Sep-2012 7:47:16 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [MVC] in context with path [/MVC] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException
at com.wbkit.mvc.util.SendMail.confirmRegistrationMail(SendMail.java:79)
at com.wbkit.mvc.web.main.RegisterController.save(RegisterController.java:276)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
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.doPost(FrameworkServlet.java:789)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:999)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1812)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
java.lang.NullPointerException at com.wbkit.mvc.util.SendMail.confirmRegistrationMail(SendMail.java:79) points to
MimeMessage message = mailSender.createMimeMessage();
in SendMail.java. I removed some of the commented code I had.
Thanks for your suggestions and help.
I've had the same error. It came from a manual instantiation of the class that had the JavaMailSender bean as an autowired field. In the code posted by the OP, that would be the SendMail service class.
This question shed some light on the phenomenon: the autowired fields of the manually created object did not receive any actual reference to the JavaMailSender bean because Spring can't know it is supposed to do its magic then. It's very obvious afterwards.
Hope this helps someone.
It seems that you've included everything except the details of your exception.
Also, it looks like you're just making up property names. A bunch of the properties in your configuration are not valid JavaMail properties. Also, see this list of common mistakes.
Check your logging when the application starts up and see if you can see the JavaMailSender being wired into SendMail. You may have to set the org.springframework logging to DEBUG.
It seems to me that your wiring must be wrong, though I can't see why yet.
Remove the #Autowired from SimpleMailMessage and create the object of it inside confirmRegistrationMail() method:
public void confirmRegistrationMail(User user) {
SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
}
This is probably because it's recommended to use the #Autowire for interface. e.g. JavaMailSender
Write #Service annotation on your helper class in which you have done the autowiring. And then use the #autowire annotation in the class where you are using that class.