Spring 3, Hibernate 4 AutoWired sessionFactory with Generic DAO - spring-mvc

Using Spring MVC 3 & Hibernate 4 I'm getting:
java.lang.NullPointerException
com.daniel.rr.dao.common.DAOImpl.getSession(DAOImpl.java:22)
com.daniel.rr.dao.common.DAOImpl.save(DAOImpl.java:27)
com.daniel.rr.controller.HelloController.printWelcome(HelloController.java:30)
This is the relevant spring configuration:
<context:annotation-config />
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="packagesToScan">
<list>
<value>com.daniel.rr.model</value>
<value>com.daniel.rr.dao</value>
<value>com.daniel.rr.dao.common</value>
<value>com.daniel.rr.controller</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="url" value="jdbc:mysql://localhost:3306/rr" />
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="username" value="root" />
<property name="password" value="" />
</bean>
<bean name="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
Generic DAO:
public interface DAO<T> {
T save(T t);
void delete(T t);
}
#Transactional
public abstract class DAOImpl<T> implements DAO<T> {
#Autowired
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public Session getSession() {
return sessionFactory.getCurrentSession();
}
#Override
public T save(T t) {
getSession().persist(t);
return t;
}
#Override
public void delete(T t) {
getSession().delete(t);
}
}
AccountDAO:
public class AccountDAO extends DAOImpl<Account> implements DAO<Account> {
}
MVC Controller:
public class HelloController {
#RequestMapping(method = RequestMethod.GET)
public String printWelcome(ModelMap model) {
//System.out.println("is null? " + sessionFactory);
AccountDAO dao = new AccountDAO();
Account account = new Account();
account.setUsername("hello");
account.setPassword("test");
dao.save(account);
model.addAttribute("message", "Hello world!");
return "hello";
}
}
I've searched thru StackOverflow and Google but I cannot find anything that helps.
I've tried using a Transaction on DAOImpl.save(T t) but it still has the same issue.
public T save(T t) {
Transaction tr = getSession().getTransaction();
tr.begin();
getSession().persist(t);
tr.commit();
return t;
}

Annotations are not inherited.
Add the transactional annotation to the concrete dao, not the abstract class.
You might like this too

Related

I don't need shiro.ini on spring webmvc

I'm developing a web application based on spring webmvc and apache shiro.
I made JpaRealm class which extends AuthorizingRealm, and it is instantiated by Spring context in order to inject dependency (UserService).
I don't need shiro.ini file because all of configurations are overriden by spring-context.xml.
If I delete it, the default listener compains because the default IniWebEnvironment always tries to load shiro.ini.
I'd like to ask the custom listener which load the custom environment extends DefaultWebEnvironment.
I copied someone's code from the Internet, but I failed.
public class JpaRealm extends AuthorizingRealm {
private static final Logger logger = LoggerFactory.getLogger(JpaRealm.class);
#Autowired
private UserService userService;
public JpaRealm() {
HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
credentialsMatcher.setHashAlgorithmName(Sha256Hash.ALGORITHM_NAME);
setCredentialsMatcher(credentialsMatcher);
}
#Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
SimpleAuthenticationInfo info = null;
UsernamePasswordToken userPassToken = (UsernamePasswordToken) token;
String username = userPassToken.getUsername();
if (username != null && !username.equals("")) {
User user = userService.findByUsername(username);
logger.debug("doGetAuthenticationInfo invoked");
logger.debug("username: " + username);
info = new SimpleAuthenticationInfo(username, user.getPassword(), getName());
}
return info;
}
#Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
AuthorizationInfo authorizationInfo = null;
if (principals != null) {
logger.debug("doGetAuthorizationInfo invoked");
String username = (String) getAvailablePrincipal(principals);
return userService.getAuthorizationInfoByUser(username);
}
return authorizationInfo;
}
}
security-context.xml
<bean id="jpaRealm" class="foo.bar.JpaRealm" />
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="jpaRealm" />
</bean>
<bean id="verboseFormAuthenticationFilter"
class="foo.bar.VerboseFormAuthenticationFilter">
<property name="loginUrl" value="/login.jsp" />
<property name="successUrl" value="/" />
<property name="usernameParam" value="username" />
<property name="passwordParam" value="password" />
<property name="rememberMeParam" value="rememberMe" />
<property name="failureKeyAttribute" value="yamShiroLoginFailure" />
</bean>
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<property name="unauthorizedUrl" value="/unauthorized.jsp" />
<property name="filters">
<map>
<entry key="authc" value-ref="verboseFormAuthenticationFilter" />
</map>
</property>
<property name="filterChainDefinitions">
<value>
/**=authc
</value>
</property>
</bean>
I found my answer from the manual, and it works fine.
shiroEnvironmentClass can be replaced as a context-param as follows:
web.xml
<listener>
<listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
</listener>
<!-- IniWebEnvironment is not requied because shiro.ini is not necessary. -->
<context-param>
<param-name>shiroEnvironmentClass</param-name>
<param-value>org.apache.shiro.web.env.DefaultWebEnvironment</param-value>
</context-param>

Getting "no transaction is in progress" when calling em.flush();

Hi i am trying to integrate jpa with spring mvc and getting "no transaction is in progress" when trying to call flush() method.
I can make out that something is wrong with transactions even though i have used #Transactional the method is not running in a transaction.
Spring.xml
`<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<!-- Root Context: defines shared resources visible to all other web components -->
<context:annotation-config />
<context:component-scan base-package="com.sushant.mvc" />
<bean class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close" id="dataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://127.0.0.1/mvc" />
<property name="username" value="root" />
<property name="password" value="root" />
<property name="testOnBorrow" value="true" />
<property name="testOnReturn" value="true" />
<property name="testWhileIdle" value="true" />
<property name="timeBetweenEvictionRunsMillis" value="1800000" />
<property name="numTestsPerEvictionRun" value="3" />
<property name="minEvictableIdleTimeMillis" value="1800000" />
<property name="validationQuery" value="SELECT 1" />
<property name="maxActive" value="-1" />
<property name="maxIdle" value="-1" />
<!-- This property should be set to a value so as to support minimum 500
BC concurrent connections. For test, set this value to 5 -->
<property name="initialSize" value="5" />
</bean>
<bean class="org.springframework.orm.jpa.JpaTransactionManager"
id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven mode="proxy" transaction-manager="transactionManager"/>
<bean
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
id="entityManagerFactory">
<property name="persistenceUnitName" value="persistenceUnit" />
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<!-- <property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">create</prop>
</props>
</property> -->
</bean>
<bean
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor">
<property name="defaultPersistenceUnitName" value="persistenceUnit" />
</bean>
<!-- <bean id="user" class="com.sushant.mvc.entities.User"/> -->
</beans>
`
User.java
'
package com.sushant.mvc.entities;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.PersistenceContext;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
#Entity
#Component
#Configurable
public class User {
#PersistenceContext(name = "persistenceUnit")
transient public EntityManager em;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column
private String userName;
#Column
private String email;
#Column
private String firstName;
#Column
private String lastName;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public static final EntityManager entityManager() {
EntityManager em = new User().em;
if (em == null)
throw new IllegalStateException(
"Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
return em;
}
#Transactional
public void save(User user) {
em.persist(user);
em.flush();
}
}
'
HomeController.java
'
package com.sushant.mvc;
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.RequestMethod;
import com.sushant.mvc.entities.User;
/**
* Handles requests for the application home page.
*/
#Controller
public class HomeController {
#Autowired
User user;
private static final Logger logger = LoggerFactory
.getLogger(HomeController.class);
/**
* Simply selects the home view to render by returning its name.
*/
#Transactional
#RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
logger.info("Welcome home! the client locale is " + locale.toString());
//user.em.getTransaction().begin();
// User user=new User();
user.setEmail("sushantmahajan05#gmail.com");
user.setFirstName("Sushant");
user.setLastName("Mahajan");
user.setUserName("sushantmahajan05");
user.save(user);
User u=user.em.find(User.class, new Integer(1).longValue());
Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG,
DateFormat.LONG, locale);
String formattedDate = dateFormat.format(date);
model.addAttribute("serverTime", formattedDate);
return "home/home";
}
}
'
servlet-context.xml
'
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC #Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by #Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<context:component-scan base-package="com.sushant.mvc" />
</beans:beans>
'
You may try creating a persistence.xml file .
You can take a look at te following example : JTASessionContext being used with JDBCTransactionFactory; auto-flush will not operate correctly with getCurrentSession()

Bootstrap with Spring MVC

I am trying to use bootstrap to style my app but I won't apply the styles. This is what is in my JSP
<c:url value="css/bootstrap.min.css" var="cssBoostrap" />
<link href="${cssBootstrap}" rel="stylesheet">
This css folder is on the same level as WEB-INF not inside of it but it won't work if it is inside of it or even if the files are inside of the view dir. What could the problem possibly be? I no longer get the no mapping error when adding the mapping to my servlet.xml but yet it still doesn't see the file or I can assume it doesn't because no styling is applied, then I change it to link to the online hosted version and all my styles are applied correctly.
Servlet XML
<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"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<!-- Scans for annotated #Controllers in the classpath -->
<context:component-scan base-package="com.eaglecrk.recognition" />
<mvc:annotation-driven />
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:properties/system.properties</value>
</list>
</property>
</bean>
<!-- messageSource -->
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>file:${external.property.directory}PMS.EOTM.SendEmail</value>
</list>
</property>
</bean>
<!-- dataSource -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- session factory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</prop>
<prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
<prop key="hibernate.cache.provider_class">${hibernate.cache.provider_class}</prop>
</props>
</property>
<property name="packagesToScan" value="com.eaglecrk.recognition.persistence" />
</bean>
<!-- Transaction Manager -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="javaMailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value = "${email.host}" />
<property name="port" value="${email.port}" />
<property name="username" value="${email.username}" />
<property name="password" value="${email.password}" />
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.ssl.trust">${email.mail.smtp.ssl.trust}</prop>
<prop key="mail.smtp.starttls.enable">${email.mail.smtp.starttls.enable}</prop>
<prop key="mail.smtp.auth">${email.mail.smtp.auth}</prop>
</props>
</property>
</bean>
</beans>
Controller
package com.eaglecrk.recognition.controller;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import com.eaglecrk.recognition.dao.award.AwardDao;
import com.eaglecrk.recognition.dao.award.AwardDaoInterface;
import com.eaglecrk.recognition.dao.employee.EmployeeDaoInterface;
import com.eaglecrk.recognition.model.AwardTypeModel;
import com.eaglecrk.recognition.model.EmployeeModel;
import com.eaglecrk.recognition.persistence.AwardNomination;
import com.eaglecrk.recognition.persistence.AwardType;
import com.eaglecrk.recognition.persistence.Employee;
import com.eaglecrk.recognition.util.Functions;
import com.eaglecrk.recognition.util.SpringMailSender;
#Controller
public class TestController extends BaseController implements MessageSourceAware {
private static final Logger LOG = LogManager
.getLogger(TestController.class);
#Autowired
private EmployeeDaoInterface employeeDao;
#Autowired
private AwardDaoInterface awardDao;
#Autowired
private SpringMailSender springMailSender;
/**
* #param request
* #return (ModelAndView) object
*/
#RequestMapping(value = "/test", method = RequestMethod.GET)
public ModelAndView test() {
try {
LOG.info("Entered the controller");
springMailSender.sendMail();
} catch (Exception e) {
e.printStackTrace();
}
ModelAndView mav = new ModelAndView();
ArrayList<String> names = new ArrayList<String>();
List<Employee> employees = employeeDao.findAll();
Collections.sort(employees, Functions.lastNameOrder);
for (Employee employee : employees) {
EmployeeModel model = new EmployeeModel(employee);
names.add(model.getLocation().getLocationId() + " " +
model.getFirstName() + " " + model.getLastName());
}
mav.addObject("names", names);
mav.setViewName("test");
return mav;
}
#RequestMapping(value = "/test", method = RequestMethod.POST)
public void addNomination(
#ModelAttribute("SpringWeb") AwardNomination nomination,
ModelMap model) {
}
#RequestMapping(value = "/login", method = RequestMethod.GET)
public ModelAndView login() {
ModelAndView mav = new ModelAndView();
mav.setViewName("login");
return mav;
}
#RequestMapping(value="/newAwardType", method=RequestMethod.GET)
public ModelAndView addAward() {
ModelAndView mav = new ModelAndView();
ArrayList<AwardTypeModel> models = new ArrayList<AwardTypeModel>();
try{
AwardTypeModel newAwardTypeModel = new AwardTypeModel();
newAwardTypeModel.setActive(false);
newAwardTypeModel.setName("AwardTypeModel.name");
newAwardTypeModel.setDescription("AwardTypeModel.description");
// newAwardTypeModel.setId(123456);
newAwardTypeModel.setCreated(new Date());
newAwardTypeModel.setModified(new Date());
models.add(newAwardTypeModel);
} catch (Exception e){
e.printStackTrace();
}
mav.addObject("awardTypes", models);
mav.addObject("model", new AwardTypeModel());
mav.setViewName("addAward");
return mav;
}
#RequestMapping(value="/addAward", method=RequestMethod.POST)
public String addAwardForm(#ModelAttribute("model") AwardTypeModel model, BindingResult result){
model.setCreated(new Date());
model.setModified(new Date());
AwardType dbo = (AwardType) model.convertToDb();
awardDao.save(dbo);
return "redirect:/test";
}
#Override
public void setMessageSource(MessageSource messageSource) {
// TODO Auto-generated method stub
}
}
Create one folder by name resources at same level as WEB-INF as shown below:
WebApp-|
| - resources -|
| |-styles-|
| | |-bootstrap.min.css
| |
| |-javascript-|
| |-example.js
|
| - WEB-INF
Include the following line in your servlet xml:
<mvc:resources mapping="/resources/**" location="/resources/"/>
Access these resources in your jsp as:
<%#taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<link href="<c:url value="/resources/styles/bootstrap.min.css" />" rel="stylesheet">
<script src="<c:url value="/resources/javascript/example.js" />"></script>
....
You should declare in your dispatcher servlet config the location of you resources (e.g js, css, img etc.) :
<mvc:resources mapping="/public/**" location="/public/" />
location contains the path to your resources folder. mapping is how you call your resources in your jsp.
Don't forget to declare your mvc namespace in dispatcher config.
Following Prasads Answer above if you need Java based configuration for the same use -
#Configuration
#ComponentScan("com.eaglecrk.recognition")
#EnableWebMvc
public class SpringConfig extends WebMvcConfigurerAdapter {
#Bean
public UrlBasedViewResolver setupViewResolver() {
UrlBasedViewResolver resolver = new UrlBasedViewResolver();
resolver.setPrefix("/WEB-INF/jsp/");
resolver.setSuffix(".jsp");
resolver.setViewClass(JstlView.class);
return resolver;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
Also if you are using xml based configuration don't forget <mvc:default-servlet-handler/>

spring 3 autowire

I'm using spring3 and hibernate 3 to build my application, I can't autowire the session factory
package com.dao;
import java.util.List;
import org.hibernate.SessionFactory;
import org.hibernate.classic.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import com.gepmag.model.Message;
#Repository("iMessageTicketDao")
public class MessageTicketDaoImpl implements IMessageTicketDao {
#Autowired
private SessionFactory sessionFactory;
#Override
public void saveMessage(Message message) {
// TODO Auto-generated method stub
sessionFactory.getCurrentSession().save(message);
}
#Override
public List<Message> listTicketMessages(Long IdTicket) {
// TODO Auto-generated method stub
List<Message> list = sessionFactory.getCurrentSession()
.createQuery("from Message where IdTicket=?")
.setParameter(0, IdTicket).list();
return list;
}
#Override
public void deleteMessage(Message message) {
// TODO Auto-generated method stub
sessionFactory.getCurrentSession().delete(message);
}
#Override
public void updateMessage(Message message) {
// TODO Auto-generated method stub
sessionFactory.getCurrentSession().update(message);
}
#Override
public Message getMessageById(int idMessage) {
// TODO Auto-generated method stub
List<Message> list = sessionFactory.getCurrentSession()
.createQuery("from Message where where IdMessage=?")
.setParameter(0, idMessage).list();
return (Message) list.get(0);
}
#Override
public List<Message> listAllMessages() {
// TODO Auto-generated method stub
List<Message> list = sessionFactory.getCurrentSession()
.createQuery("from Message").list();
return list;
}
}
And context xml configuration:
<?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:tx="http://www.springframework.org/schema/tx" 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/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd ">
<context:annotation-config/>
<context:property-placeholder location="classpath:jdbc.properties" />
<context:component-scan base-package="com.gepmag" />
<tx:annotation-driven transaction-manager="hibernateTransactionManager" />
<!-- <context:annotation-driven/> -->
<mvc:annotation-driven />
<bean id="jspViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${database.driver}" />
<property name="url" value="${database.url}" />
<property name="username" value="${database.user}" />
<property name="password" value="${database.password}" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.gepmag.model"/>
<property name="annotatedClasses">
<list>
<value>com.model.Client</value>
<value>com.model.Erreurs</value>
<value>com.model.Message</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
</props>
</property>
</bean>
<bean id="hibernateTransactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="messageSource"
class="com.service.MessageBundle">
<property name="basename" value="com.service.MessageBundle" />
</bean>
</beans>
I always have this exception
SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/PortailSupport] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException
at com.gepmag.dao.MessageTicketDaoImpl.saveMessage(MessageTicketDaoImpl.java:49)
at com.gepmag.service.TicketMessageServiceImpl.saveMessage(TicketMessageServiceImpl.java:48)
this is the service
package com.gepmag.service;
#Service("iTicketMessageService")
#Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public class TicketMessageServiceImpl implements ITicketMessageService {
#Autowired(required=true)
private IMessageTicketDao iMessageTicketDao;
#Override
public void saveMessage(Message message) {
// TODO Auto-generated method stub
iMessageTicketDao.saveMessage(message);
}
#Override
public List<Message> listTicketMessages(Long IdTicket) {
// TODO Auto-generated method stub
List<Message> list = iMessageTicketDao.listTicketMessages(IdTicket);
return list;
}
#Override
public void deleteMessage(Message message) {
// TODO Auto-generated method stub
iMessageTicketDao.deleteMessage(message);
}
#Override
public void updateMessage(Message message) {
// TODO Auto-generated method stub
iMessageTicketDao.updateMessage(message);
}
#Override
public Message getMessageById(int idMessage) {
// TODO Auto-generated method stub
Message message = iMessageTicketDao.getMessageById(idMessage);
return message;
}
#Override
public List<Message> listAllMessages() {
// TODO Auto-generated method stub
List<Message> list = iMessageTicketDao.listAllMessages();
return list;
}
}
my controller
#Controller
#RequestMapping("/forms/ticket")
public class TicketController {
#Autowired
private TicketMessageServiceImpl iTicketMessageService ;
#RequestMapping(value="/addticket", method = RequestMethod.GET)
public String addTicket(Map model) {
TicketForm ticket = new TicketForm();
List<CategorieTicket> categorieList = LoadCategorieList();
List<SeveriteTicket> severiteList = LoadSeveriteList();
List<PrioriteTicket> prioriteList = LoadPrioriteList();
List<ProblemeTicket> problemeList = LoadProblemeList();
List<EtatSysteme> etatSystemeList = LoadEtatSysteme();
List<ContexteProblemeTicket> contexteList = LoadContexteProblemeTicket();
List<EtatInstance> etatInstanceList = LoadEtatInstance();
model.put("ticket", ticket);
model.put("categorieList", categorieList);
model.put("severiteList", severiteList);
model.put("prioriteList", prioriteList);
model.put("problemeList", problemeList);
model.put("etatSystemeList", etatSystemeList);
model.put("contexteList", contexteList);
model.put("etatInstanceList", etatInstanceList);
return "newticket";
}
public List<CategorieTicket> LoadCategorieList(){
List <CategorieTicket>categorieList = new ArrayList<CategorieTicket>();
categorieList.add(new CategorieTicket(1,"Nouveau Besoin","description du nouveau besoin"));
categorieList.add(new CategorieTicket(2,"Anomalie","description de l'anomalie"));
categorieList.add(new CategorieTicket(3,"incident de production","description de l'incident de la production"));
categorieList.add(new CategorieTicket(4,"crise de production","description du crise de la production"));
return categorieList;
}
public List<SeveriteTicket> LoadSeveriteList(){
List<SeveriteTicket> severiteList = new ArrayList<SeveriteTicket>();
severiteList.add(new SeveriteTicket(1,"Bloquant","description de la sévérité bloquante"));
severiteList.add(new SeveriteTicket(2,"Critique","description de la sévérité critique"));
severiteList.add(new SeveriteTicket(3,"Majeur","description de la sévérité majeure"));
severiteList.add(new SeveriteTicket(4,"Mineur","description de la sévérité mineur"));
return severiteList;
}
public List<PrioriteTicket> LoadPrioriteList(){
List<PrioriteTicket> PrioriteList = new ArrayList<PrioriteTicket>();
PrioriteList.add(new PrioriteTicket(1,"Faible","priorité faible"));
PrioriteList.add(new PrioriteTicket(2,"Moyenne","priorité moyenne"));
PrioriteList.add(new PrioriteTicket(3,"Haute","priorité forte"));
return PrioriteList;
}
public List<ProblemeTicket> LoadProblemeList(){
List<ProblemeTicket> ProblemeList = new ArrayList<ProblemeTicket>();
ProblemeList.add(new ProblemeTicket(1,"Dysfonctionnement c2o","probleme de fonctionnement c2o") );
ProblemeList.add(new ProblemeTicket(2,"Problème d'installation","probleme d'installation") );
ProblemeList.add(new ProblemeTicket(3,"Modification licence","probleme de modification de la licence"));
return ProblemeList;
}
public List<EtatSysteme> LoadEtatSysteme(){
List<EtatSysteme> StateSystemList = new ArrayList<EtatSysteme>();
StateSystemList.add(new EtatSysteme(1,"Complètement bloqué","Systeme complètement bloqué"));
StateSystemList.add(new EtatSysteme(2,"Fortement perturbé","Systeme fortement perturbé"));
StateSystemList.add(new EtatSysteme(3,"Perturbation résiduelle","Systeme qui est Perturbé résiduellement"));
return StateSystemList;
}
public List<ContexteProblemeTicket> LoadContexteProblemeTicket(){
List<ContexteProblemeTicket> ContexteList = new ArrayList<ContexteProblemeTicket>();
ContexteList.add(new ContexteProblemeTicket(1,"Lors de l'installation",""));
ContexteList.add(new ContexteProblemeTicket(2,"En cours de l'exécution",""));
return ContexteList;
}
public List<EtatInstance> LoadEtatInstance(){
List<EtatInstance> EtatInstanceList = new ArrayList<EtatInstance>();
EtatInstanceList.add(new EtatInstance(1,"Aborté"," instance aborté"));
EtatInstanceList.add(new EtatInstance(2,"En attente","instance en attente"));
return EtatInstanceList;
}
#RequestMapping("/ticketvalide.html")
public String processTicketForm(Map model,#Valid #ModelAttribute("ticket") TicketForm ticket){
Message message = new Message();
message.setObjet(ticket.getSujetTicket());
message.setTextMessage(ticket.getMessageTicket());
message.setPath(ticket.getFile());
iTicketMessageService.saveMessage(message);
return "detailsticket";
}
}

Spring MVC Content Negotiation with HttpMessageConverter

For a recent project we wanted to support XML and another format for our resopnses.
However, we could not control the Accept header. Hence we configured a ContentNegotiatingViewResolver to use a request parameter instead:
<bean id="viewResolver" class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="favorParameter" value="true" />
<property name="parameterName" value="format" />
<property name="ignoreAcceptHeader" value="true" />
<property name="defaultContentType" value="application/xml" />
<property name="mediaTypes">
<map>
<entry key="xml" value="application/xml" />
<entry key="foo" value="application/x-foo" />
</map>
</property>
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver" >
<property name="basename" value="views-xml" />
</bean>
<bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver" >
<property name="basename" value="views-foo" />
</bean>
</list>
</property>
</bean>
Now however, I was wondering if I could move to using #ResponseBody and HttpMessageConverter implementations to simplify the amount of code I need to maintain.
However, is there a similar way to ensure that a reqeust parameter is used for content negotiation, instead of the Accept header?
There is a workaround, as described at https://jira.springframework.org/browse/SPR-7517
Create a subclass of AnnotationMethodHandlerAdapter:
package org.nkl.spring;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.MediaType;
import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter;
public class MyAnnotationMethodHandlerAdapter extends AnnotationMethodHandlerAdapter {
private Logger logger = LoggerFactory.getLogger(MyAnnotationMethodHandlerAdapter.class);
private String requestParam = "accept";
private Map<String, MediaType> mediaTypesMap;
#Override protected HttpInputMessage createHttpInputMessage(HttpServletRequest request) throws Exception {
HttpInputMessage message = super.createHttpInputMessage(request);
String accept = request.getParameter(requestParam);
if (accept == null || accept.isEmpty()) {
logger.info(String.format("Request parameter [%s] not found. Using standard HttpInputMessage", requestParam));
return message;
} else {
logger.info(String.format("Request parameter [%s] was [%s]", requestParam, accept));
MediaType mediaType = mediaTypesMap.get(accept);
if (mediaType == null) {
logger.info(String.format("Suitable MediaType not found. Using standard HttpInputMessage"));
return message;
} else {
logger.info(String.format("Suitable MediaType [%s] found. Using custom HttpInputMessage", mediaType));
return new MyHttpInputMessage(message, mediaTypesMap.get(accept));
}
}
}
public void setMediaTypesMap(Map<String, MediaType> mediaTypesMap) {
this.mediaTypesMap = mediaTypesMap;
}
public void setRequestParam(String requestParam) {
this.requestParam = requestParam;
}
}
Create a Decorator of HttpInputMessage:
package org.nkl.spring;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.MediaType;
public class MyHttpInputMessage implements HttpInputMessage {
private HttpInputMessage delegate;
public MyHttpInputMessage(HttpInputMessage delagate, MediaType mediaType) {
this.delegate = delagate;
this.delegate.getHeaders().setAccept(Arrays.asList(mediaType));
}
#Override public InputStream getBody() throws IOException {
return this.delegate.getBody();
}
#Override public HttpHeaders getHeaders() {
return this.delegate.getHeaders();
}
}
Configure your bean like:
<bean class="org.nkl.spring.MyAnnotationMethodHandlerAdapter">
<property name="requestParam" value="format" />
<property name="mediaTypesMap">
<util:map>
<entry key="plain" value="text/plain" />
<entry key="xml" value="text/xml" />
</util:map>
</property>
<property name="messageConverters">
<util:list>
... converters go here ...
</util:list>
</property>
</bean>
Newer versions of Spring can now do this. The ContentNegotiationManagerFactoryBean can create a content negotiation manager that does precisely what you want here. See my answer to a related question.

Resources