How to manage persistence using Spring and Hibernate - java

I just started a web application in Spring using Hibernate and this is the way I figured(after finding few ways of doing it):
GenericDAO
public interface GenericDAO<T extends DomainModel> {
public T getById(Integer id);
public List<T> getAll();
public void saveEntity(T object);
public void deleteEntity(T object);
}
GenericDAOImpl
public class GenericDAOImpl<T extends DomainModel> implements GenericDAO<T> {
private Class<T> type;
#Autowired
protected SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory){
this.sessionFactory = sessionFactory;
}
public Session getCurrentSession(){
return sessionFactory.getCurrentSession();
}
public GenericDAOImpl(Class<T> type) {
super();
this.type = type;
}
#SuppressWarnings("unchecked")
#Transactional(readOnly = true)
#Override
public T getById(Integer id) {
if( id == null){
return null;
} else {
return (T) getCurrentSession().get(type, id);
}
}
#SuppressWarnings("unchecked")
#Transactional(readOnly = true)
#Override
public List<T> getAll() {
return getCurrentSession().createQuery("select o from " + type.getName() + " o").list();
}
#Transactional(readOnly = true)
#Override
public void saveEntity(T object) {
getCurrentSession().persist(object);
}
#Transactional(readOnly = true)
#Override
public void deleteEntity(T object) {
getCurrentSession().delete(object);
}
}
UserService
public interface UserService {
public void addUser(User user);
public List<User> getUsers();
public User get(Integer id);
public void delete(User user);
}
UserServiceImpl
#Service
#Transactional
public class UserServiceImpl implements UserService {
#Autowired
private GenericDAO<User> userDAO;
#Override
public void addUser(User user) {
userDAO.saveEntity(user);
}
#Override
public User get(Integer id) {
return userDAO.getById(id);
}
#Override
public void delete(User user) {
userDAO.deleteEntity(user);
}
#Override
public List<User> getUsers() {
return userDAO.getAll();
}
}
UserController
#Controller
public class UserController {
#Autowired
private UserService userService;
#RequestMapping(value = "test", method = RequestMethod.GET)
public String test(){
User u1 = userService.get(1);
return "test";
}
}
Configuration hibernate
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<bean id="myDataSource" 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/online_auction" />
<property name="username" value="root" />
<property name="password" value="123456" />
</bean>
<!-- Hibernate 4 SessionFactory Bean definition -->
<bean id="mySessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="packagesToScan" value="online_auction.domain_model" />
<property name="hibernateProperties">
<props>
<!-- SQL dialect depends on which database you connect to -->
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="mySessionFactory"></property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<mvc:annotation-driven/>
</beans>
Configuration Spring
<?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:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
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-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">
<import resource="classpath:dataSource.xml"/>
<mvc:annotation-driven />
<context:component-scan base-package="online_auction"/>
<mvc:resources location="css" mapping="/css/**" />
<mvc:resources location="images" mapping="/images/**" />
<!-- Tiles configuration -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass">
<value>
org.springframework.web.servlet.view.tiles2.TilesView
</value>
</property>
</bean>
<bean id="tilesConfigurer"
class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/tiles.xml</value>
</list>
</property>
</bean>
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
</beans>
My questions are:
How is the management of the database connection made ? Session per
web Request ? When is the database connection opened and closed ?
Should I create the session in the Service and pass it as parameter to the repositories constructors. Should I also manipulate the session methods like : open session, begin transaction, commit, close session.
Since is my first layered application using Repository and Service any suggestions on how to manage database connection/session/transaction are more then welcomed. Thanks in advance!

A pointer for few of your queries - Consider using Spring's OpenSessionInViewInterceptor, it binds Hibernate Session to the thread for the entire processing of the request. You can have it's bean defined as:
<bean name="openSessionInViewInterceptor"
class="org.springframework.orm.hibernate4.support.OpenSessionInViewInterceptor">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
and referred in "interceptors" property of SimpleUrlHandlerMapping bean in Spring's context.xml.
More detail on OpenSessionInViewInterceptor here.

Related

Exception:No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here

I am getting error after deploying the application. I have checked similar questions but still could not resolve the error. I have used #Transactional for the service class as well as
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:656)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Root Cause
org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
org.springframework.orm.hibernate3.SpringSessionContext.currentSession(SpringSessionContext.java:63)
org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:687)
com.utd.dao.CustomerDaoImpl.getAllCustomer(CustomerDaoImpl.java:22)
com.utd.service.CustomerManagerImpl.getAllCustomer(CustomerManagerImpl.java:23)
com.utd.controller.CustomerController.listCustomers(CustomerController.java:22)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
I have following project files:
The controller:
#Controller
public class CustomerController {
#Autowired
private CustomerManager customerManager;
#RequestMapping(value="/", method= RequestMethod.GET)
public String listCustomers(ModelMap map){
map.addAttribute("customer", new Customer());
map.addAttribute("customerList", customerManager.getAllCustomer());
return "CustomerList";
}
#RequestMapping(value = "/add", method = RequestMethod.POST)
public String addCustomer(#ModelAttribute(value="customer") Customer customer, BindingResult result)
{
customerManager.addCustomer(customer);
return "redirect:/";
}
#RequestMapping("/delete/{customerId}")
public String deleteEmplyee(#PathVariable("customerId") Integer customerId)
{
customerManager.deleteCustomer(customerId);
return "redirect:/";
}
public void setCustomerManager(CustomerManager customerManager) {
this.customerManager = customerManager;
}
}
The dao class
public class CustomerDaoImpl implements CustomerDao{
#Autowired
private SessionFactory sessionFactory;
public void addCustomer(Customer customer) {
this.sessionFactory.getCurrentSession().save(customer);
}
#SuppressWarnings("unchecked")
public List<Customer> getAllCustomer() {
return this.sessionFactory.getCurrentSession().createQuery("from Customer").list();
}
public void deleteCustomer(Integer customerId) {
Customer customer = (Customer) sessionFactory.getCurrentSession().load(Customer.class, customerId);
if (null != customer) {
this.sessionFactory.getCurrentSession().delete(customer);
}
}
}
The Dto:
#Entity
#Table(name="Customer")
public class Customer {
#Id
#Column(name="ID")
#GeneratedValue
private int id;
#Column(name="NAME")
private String name;
#Column(name="CONTACT")
private String contact;
#Column(name="EMAIL")
private String email;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getContact() {
return contact;
}
public void setContact(String contact) {
this.contact = contact;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
customer-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: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:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/util/ http://www.springframework.org/schema/util/spring-util.xsd">
<context:annotation-config />
<context:component-scan base-package="com.utd.controller" />
<bean id="jspViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView"></property>
<property name="prefix" value="/WEB-INF/view/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages"></property>
<property name="defaultEncoding" value="UTF-8"></property>
</bean>
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="/WEB-INF/jdbc.properties"></bean>
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.databaseurl}" p:username="${jdbc.username}"
p:password="${jdbc.password}"></bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${jdbc.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="customerDao" class="com.utd.dao.CustomerDaoImpl"></bean>
<bean id="customerManager" class="com.utd.service.CustomerManagerImpl"></bean>
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
</beans>
dispatcher-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"
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">
<mvc:annotation-driven />
<context:component-scan base-package="com.utd" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
Manager class Implementation
package com.utd.service;
import com.utd.dao.CustomerDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.utd.dto.Customer;
import javax.transaction.Transactional;
import java.util.List;
#Service
public class CustomerManagerImpl implements CustomerManager {
#Autowired
private CustomerDao customerDao;
#Transactional
public void addCustomer(Customer customer) {
customerDao.addCustomer(customer);
}
#Transactional
public List<Customer> getAllCustomer() {
return customerDao.getAllCustomer();
}
#Transactional
public void deleteCustomer(Integer customerId) {
customerDao.deleteCustomer(customerId);
}
public void setCustomerDao(CustomerDao customerDao) {
this.customerDao = customerDao;
}
}
I would like to know how to resolve the error.

Spring3 - Autowired is not happening. The object is null

servlet.xml
I am using annotation instead of creating bean in XML.
And I have added the "context: annotation-config" in my XML
<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.xsd">
<context:component-scan base-package="com.hemanths.expense.manager"/>
<mvc:annotation-driven/>
<tx:annotation-driven/>
<context:annotation-config />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="configLocation" value="WEB-INF/hibernate.cfg.xml"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
</beans>
UserDaoImpl.java
package com.hemanths.expense.manager.hibernate.dao.impl;
import com.hemanths.expense.manager.hibernate.dao.UserDao;
import com.hemanths.expense.manager.hibernate.entity.User;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.List;
#Repository
public class UserDaoImpl implements UserDao {
#Autowired
private SessionFactory sessionFactory;
public UserDaoImpl() {
}
public UserDaoImpl(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
#Override
public void addUser(User user) {
sessionFactory.getCurrentSession().save(user);
}
}
UserService.java
package com.hemanths.expense.manager.service.impl;
import com.hemanths.expense.manager.hibernate.dao.UserDao;
import com.hemanths.expense.manager.hibernate.entity.User;
import com.hemanths.expense.manager.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
#Service
public class UserServiceImpl implements UserService {
#Autowired
private UserDao userDao;
public UserServiceImpl() {
}
public UserServiceImpl(UserDao userDao){
this.userDao = userDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
#Override
#Transactional
public void addUser(User user) {
userDao.addUser(user);
}
UserServiceImplTest.java
public class UserServiceImplTest {
#Autowired
UserService userService;
#Test
public void shouldAddUser() {
User user = new User("firstName", "lastName", new Date(), "M", "username", "password");
userService.addUser(user);
}
}
Stacktrace
java.lang.NullPointerException
at com.hemanths.expense.manager.service.impl.UserServiceImplTest.shouldAddUser(UserServiceImplTest.java:18)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Directory Structure
I got an answer. Thanks #Andrei Stefan.
Because i am running a test, I have to annotate test like the below with your xml file path.
#ContextConfiguration(locations = {"classpath:mvc-dispatcher-servlet.xml"})
#RunWith(SpringJUnit4ClassRunner.class)
public class UserServiceImplTest {
#Autowired
UserService userService;
#Test
public void shouldAddUser() {
User user = new User("firstName", "lastName", new Date(), "M", "username", "password");
userService.addUser(user);
}
}
Example usage for your hibernate;
<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.xsd">
<context:component-scan base-package="com.base.package"/>
<mvc:annotation-driven/>
<tx:annotation-driven/>
<context:annotation-config />
<bean id="_hibernateSessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="configLocation" value="WEB-INF/hibernate.cfg.xml"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<!-- userDao Repo -->
<bean id="_userDao"
class="com.hemanths.expense.manager.hibernate.dao.impl.UserDaoImpl">
<property name="_hibernateSessionFactory">
<ref bean="_hibernateSessionFactory"></ref>
</property>
</bean>
<!-- userService Repo -->
<bean id="_userDao"
class="com.hemanths.expense.manager.service.impl.UserServiceImpl">
<property name="_hibernateSessionFactory">
<ref bean="_hibernateSessionFactory"></ref>
</property>
</bean>
</beans>
Add hibernate class in your DaoImpl with getter and setter :
private SessionFactory _hibernateSessionFactory;
use autowire in your controller where you want :
#Autowired
private UserServiceImpl _userServiceImpl;
As has been mentioned in the comments, you do not need to create beans for your service and DAO classes in your servlet.xml file:
<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.xsd">
<context:component-scan base-package="com.hemanths.expense.manager"/>
<mvc:annotation-driven/>
<tx:annotation-driven/>
<context:annotation-config />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="configLocation" value="WEB-INF/hibernate.cfg.xml"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
</beans>
You also do not need to supply constructors for your service and DAO classes, because they are Spring components:
#Repository("userDao")
public class UserDaoImpl implements UserDao {
#Autowired
private SessionFactory sessionFactory;
// Methods here
}
#Service
public class UserServiceImpl implements UserService {
#Autowired
private UserDao userDao;
// Methods here
}

java persistence works with reading from database,fails to insert / update

hi guys i m new to Hibernate and JPA.
This is my VO class.
Product.java
package com.sample.myproduct.valueobject;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import com.sample.myproduct.constants.MyproductConstants;
#Entity
#Table(name = "product")
#NamedQuery(
name=MyproductConstants.PRODUCT_NAMED_QUERY,
query=MyproductConstants.SELECT_QUERY_PRODUCT
)
public class Product {
#Id
#Column(name="Product_id")
int productId;
#Column(name="Name")
String name;
#Column(name="Desc")
String desc;
#Column(name="Rating")
int rating;
#Column(name="stock")
int stock;
public int getProductId() {
return productId;
}
public void setProductId(int productId) {
this.productId = productId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public int getRating() {
return rating;
}
public void setRating(int rating) {
this.rating = rating;
}
public int getStock() {
return stock;
}
public void setStock(int stock) {
this.stock = stock;
}
}
Impl Class
package com.sample.myproduct.servicedao;
import java.util.List;
import java.util.Random;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.dao.DataAccessException;
import org.springframework.transaction.annotation.Transactional;
import com.sample.myproduct.constants.MyproductConstants;
import com.sample.myproduct.valueobject.Product;
#Transactional
public class ProductDAOImpl implements ProductDAO {
#PersistenceContext
private EntityManager entityManagerFactory;
public EntityManager getEntityManagerFactory() {
return entityManagerFactory;
}
public void setEntityManagerFactory(EntityManager entityManagerFactory) {
this.entityManagerFactory = entityManagerFactory;
}
public void save(Product product){
entityManagerFactory.persist(product);
}
public Product getProductById(int id) throws DataAccessException{
return entityManagerFactory.find(Product.class,id);
}
}
}
persistance.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="JpaPersistenceUnit"
transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.sample.myproduct.servicedao.ProductDAOImpl</class>
</persistence-unit>
</persistence>
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" xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc"
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.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.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.sample.myproduct" />
<beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close" p:driverClassName="com.mysql.jdbc.Driver"
p:url="jdbc:mysql://localhost/testdb" p:username="root" p:password="" />
<beans:bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="packagesToScan" value="com.sample.myproduct" />
<beans:property name="jpaVendorAdapter">
<beans:bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</beans:property>
<beans:property name="jpaProperties">
<beans:props>
<beans:prop key="hibernate.hbm2ddl.auto">update</beans:prop>
<beans:prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</beans:prop>
<beans:prop key="hibernate.show_sql">true</beans:prop>
</beans:props>
</beans:property>
<beans:property name="persistenceUnitName" value="entityManager" />
</beans:bean>
<beans:bean class="org.springframework.orm.jpa.JpaTransactionManager"
id="transactionManager">
<beans:property name="entityManagerFactory" ref="entityManagerFactory" />
</beans:bean>
<tx:annotation-driven mode="aspectj"
transaction-manager="transactionManager" />
<context:spring-configured />
<context:annotation-config />
<beans:bean id="productService"
class="com.sample.myproduct.servicebo.ProductService">
</beans:bean>
<beans:bean id="productDAO" class="com.sample.myproduct.servicedao.ProductDAOImpl"></beans:bean>
</beans:beans>
I am able to read data from db but not able to insert data..its not giving any exception.when i added entityManager.flush() after persist function;.
its giving exception as no transaction is in progress
I am not able to find solution for this..
When using JpaTransactionManager, you should specify the dialect as well as below.
<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
<property name="jpaDialect" ref="jpaDialect"/>
</bean>
Update:
No transaction is required to read data from database but active transaction is required to write data to database.
If you don't configure the transactionManager correctly, #Transaction annotation will be ignored silently and all your operation will run as if no transaction is available; therefore, your write operation will fail.

Hibernate & Spring: EntityManager is Null

I'm setting up a Project with Spring and Hibernate. I created an abstract DAO class that contains an EntityManager. When I want to use this EntityManager, it's null and I dont understand why. Maybe you can help me.
My persistence-context
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<import resource="persistence-beans.xml" />
<mvc:annotation-driven />
<bean id="jdbcPropertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="classpath:META-INF/mysql.properties" />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}"
p:username="${jdbc.username}" p:password="${jdbc.password}" />
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="persistenceUnit" />
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="${hibernate.show_sql}" />
<property name="generateDdl" value="${hibernate.generate_ddl}" />
<property name="databasePlatform" value="${hibernate.dialect}" />
</bean>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="personDao" class="com.patrickzinner.dao.PersonDao" />
<tx:annotation-driven transaction-manager="transactionManager" />
PersonDao.java:
#Repository
#Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class PersonDao extends AbstractDao<Person> {
public PersonDao() {
super(Person.class);
}
}
AbstractDao.java
#SuppressWarnings("unchecked")
#Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public abstract class AbstractDao<T> {
#PersistenceContext
protected EntityManager em;
private Class<T> entityClass;
public AbstractDao(Class<T> entityClass) {
this.entityClass = entityClass;
}
public AbstractDao() {
}
public void create(T entity) {
this.em.persist(entity);
}
public void edit(T entity) {
this.em.merge(entity);
}
public void remove(T entity) {
this.em.remove(this.em.merge(entity));
}
public T find(long primaryKey) {
return this.em.find(entityClass, primaryKey);
}
#SuppressWarnings("rawtypes")
public List<T> findAll() {
CriteriaQuery cq = this.em.getCriteriaBuilder().createQuery();
cq.select(cq.from(entityClass));
return this.em.createQuery(cq).getResultList();
}
}
Thanks in advance!
An entity manager can only be injected in transaction classes. In other words, it can only be injected in a EJB. Other classe must use an EntityManagerFactory to create and destroy an EntityManager.
but your AbstractDAO is not EJB you can not use EntityManager directly.
solution
#PersistenceUnit(unitName = "test")
private EntityManagerFactory entityManagerFactory;
EntityManager entityManager = entityManagerFactory.createEntityManager();
then perform operation using emtityManager.
alternatively you can use container managed Transaction using JNDI lookup..
let me know for any issues.
Try adding <context:annotation-config /> to your persistence-context. This section of the reference manual may help you to use #PersistenceContext.

Hibernate doesn't update record in MySQL database

I am using PrimeFaces 3.5, JSF 2.2, Hibernate 4.1, Spring 3.2.3, MySQL in my application.
Function updateUser() is supposed to update record in the database for the selected user from the PrimeFaces dataTable component(values are correct) but for some unknown reason it doesn't. I have a class named AbstractDAO which implements CRUD operations via generics. Insertion, selection and deleting works perfectly, but update fails without showing any errors at all. Any clues what can be wrong in my code?
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:sec="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.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 http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<!-- GLOABL SETTINGS -->
<context:component-scan base-package="com.infostroy.adminportal"/>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
<!-- DATA SOURCE AND PERSISTENCE SETTINGS -->
<bean id="propertiesPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:db.properties</value>
</list>
</property>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dmDataSource"/>
<property name="packagesToScan" value="com.infostroy.adminportal"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${db.dialect}</prop>
<prop key="hibernate.show_sql">${db.show_sql}</prop>
<prop key="hibernate.hbm2ddl.auto">${db.hbm2ddl_auto}</prop>
<prop key="connection.pool_size">${db.pool_size}</prop>
<prop key="current_session_context_class">${db.current_session_context_class}</prop>
<prop key="org.hibernate.FlushMode">${db.flush_mode}</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="dataSource" ref="dmDataSource" />
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="dmDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${db.driver}" />
<property name="url" value="${db.url}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
<property name="maxWait" value="5000" />
<property name="initialSize" value="2" />
<property name="maxActive" value="100"/>
<property name="maxIdle" value="50"/>
<property name="minIdle" value="0"/>
</bean>
</beans>
db.properties:
db.username=root
db.password=root
db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost/adminportal
db.pool_size=0
db.dialect=org.hibernate.dialect.MySQLDialect
db.hbm2ddl_auto=validate
db.show_sql=true
db.current_session_context_class=thread
db.flush_mode=COMMIT
AbstractDAO:
public abstract class AbstractDAO<T extends Serializable> implements Serializable {
#Autowired
protected SessionFactory sessionFactory;
protected T object;
protected Class clazz;
public AbstractDAO(Class clazz) {
this.clazz = clazz;
}
//Executes before being removed from container
#PreDestroy
protected void destroy() {
sessionFactory.getCurrentSession().close();
}
public Session getHiberSession() {
return sessionFactory.openSession();
}
#Transactional
protected T getByID(int id) {
String queryString = "from " + clazz.getSimpleName() + " where id = :id";
Query query = getHiberSession().createQuery(queryString);
query.setInteger("id", id);
object = (T) query.uniqueResult();
return object;
}
#Transactional
protected int deleteByID(int id) {
String queryString = "delete " + clazz.getSimpleName() + " where id = :id";
Query query = getHiberSession().createQuery(queryString);
query.setInteger("id", id);
return query.executeUpdate();
}
#Transactional
protected boolean insert(T object) {
try {
getHiberSession().save(object);
return true;
} catch (HibernateException ex) {
return false;
}
}
#Transactional
protected boolean update(T object) {
try {
getHiberSession().saveOrUpdate(object);
return true;
} catch (HibernateException ex) {
return false;
}
}
#Transactional
protected List getAllRecords() {
String queryString = "from " + clazz.getSimpleName();
Query query = getHiberSession().createQuery(queryString);
return query.list();
}
}
UserDAO.java:
#Repository
public class UserDAO extends AbstractDAO<User> {
public UserDAO() {
super(User.class);
}
public User getUserById(int id) {
return super.getByID(id);
}
public int deleteUserById(int id) {
return super.deleteByID(id);
}
public boolean insertUser(User user) {
return super.insert(user);
}
public boolean updateUser(User user) {
return super.update(user);
}
public List<User> getAllUsers() {
return super.getAllRecords();
}
}
If you need any additional info or code - just tell me. Every answer is highly appreciated and responded immidiately.
Thank you.
I'm just starting with Hibernate, but I'm using sessionFactory.getCurrentSession() instead of openSession().
After saveOrUpdate() mehod just flush the session. Ex: session.flush();
For more details you can see my blog here:
http://www.onlinetutorialspoint.com/hibernate/hibernate-example.html

Categories