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

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.

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.

saveOrupdate is working in second attempt in hibernate not in first

I am working on Spring Hibernate application.
There i am trying to update Table to using session.saveOrUpdate method.
But it is not working in very first time. from second attempt i am able to update data in DB.
In first time no exception is coming. Everything is correct.
config.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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.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.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<!-- This bean configuration only for your local tomcat deployment -->
<beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<beans:property name="driverClassName" value="${db.driverClassName}" />
<beans:property name="url" value="${db.url}" />
<beans:property name="username" value="${db.username}" />
<beans:property name="password" value="${db.password}" />
</beans:bean>
<!-- weblogic server Jndi configuration for LYRA DB Datasource -->
<!-- <beans:bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<beans:property name="jndiName" value="jdbc/lyraDB" />
</beans:bean> -->
<!-- Hibernate 4 SessionFactory Bean definition -->
<beans:bean id="hibernate4AnnotatedSessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="annotatedClasses">
<beans:list>
<beans:value>com.orange.lyra.web.model.AdminGestionProfiles</beans:value>
<beans:value>com.orange.lyra.web.model.BuzonesPermisions</beans:value>
</beans:list>
</beans:property>
<beans:property name="hibernateProperties">
<beans:props>
<beans:prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect
</beans:prop>
<beans:prop key="hibernate.show_sql">true</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
<beans:bean id="scoreCardDao" class="com.orange.lyra.web.dao.impl.ScoreCardDaoImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory" />
</beans:bean>
<beans:bean id="administracionDao" class="com.orange.lyra.web.dao.impl.AdminControllerDaoImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory" />
</beans:bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<beans:bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory" />
</beans:bean>
</beans:beans>
Modal Bean class
package com.orange.lyra.web.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "LYRA_ADMIN_GESTION_PROFILE")
public class AdminGestionProfiles {
#Id
#GeneratedValue(strategy = GenerationType.TABLE)
#Column(name = "ID")
private String Id;
#Column(name = "PROFILE_ID")
private String profileIds;
#Column(name = "BUZONE_ID")
private String buzoneIds;
#Column(name = "PERMISOS_ID")
private String permisosIds;
#Column(name = "STATUS")
private String statusCheck;
public String getProfileIds() {
return profileIds;
}
public void setProfileIds(String profileIds) {
this.profileIds = profileIds;
}
public String getBuzoneIds() {
return buzoneIds;
}
public void setBuzoneIds(String buzoneIds) {
this.buzoneIds = buzoneIds;
}
public String getPermisosIds() {
return permisosIds;
}
public void setPermisosIds(String permisosIds) {
this.permisosIds = permisosIds;
}
public String getStatusCheck() {
return statusCheck;
}
public void setStatusCheck(String statusCheck) {
this.statusCheck = statusCheck;
}
}
ServiceImpl class
#Override
#Transactional
public String updatePermisosStatusByAdmin(String profileId, String buzoneID, String[] permisosIdList) {
List<AdminGestionProfiles> adminList = administracionDao.getAdminisotable(profileId,buzoneID);
for(int j =0;j<permisosIdList.length;j++)
{
for (AdminGestionProfiles adminGestionProfiles : adminList) {
if(permisosIdList[j].toString().equals(adminGestionProfiles.getPermisosIds())){
adminGestionProfiles.setStatusCheck("1");
}
}
}
String message = administracionDao.updatePermisosStatusByAdmin(adminList);
return message;
}
DaoImpl class
public class AdminControllerDaoImpl implements AdminControllerDao{
private static final Logger LOGGER = Logger .getLogger(AdminControllerDaoImpl.class);
/** The session factory. */
private SessionFactory sessionFactory;
/**
* Sets the session factory.
* #param sf
* the new session factory
*/
public void setSessionFactory(SessionFactory sf) {
this.sessionFactory = sf;
}
#Override
public String updatePermisosStatusByAdmin(List<AdminGestionProfiles> adminList) { LOGGER.debug("AdminControllerDaoImpl::updatePermisosStatusByAdmin::start");
try{
Session session = this.sessionFactory.getCurrentSession();
for (AdminGestionProfiles adminGestionProfiles : adminList) {
session.saveOrUpdate(adminGestionProfiles);
}
}catch(HibernateException error){
String err = error.getMessage();
LOGGER.debug("Hibernate Exception throw in updatePermisosStatusByAdmin mehthod ::" +err);
}
LOGGER.debug("AdminControllerDaoImpl::updatePermisosStatusByAdmin::End");
return "El proceso se ha realizado correctamente";
}
}
You are retrieving the Admins from the DB and updating some value, just call "update()" instead of "saveOrUpdate()", you know that the record already exists in the DB.
If this don't solve your problem post the exception please.
PS: Sorry for posting and answer directly, but i can't comment yet :)

Entity Manager NULL - Spring MVC JPA

In the following code the entityManager is null. What am I doing wrong? I need the entityManager to be injected automatically.
My Object Model:
#Entity
#Table(name = "jlocalidades", catalog = "7jogos")
public class Jlocalidades implements java.io.Serializable {
private Integer id;
private String nome;
private String descricao;
public Jlocalidades() {
}
public Jlocalidades(String nome, String descricao) {
this.nome = nome;
this.descricao = descricao;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "Id", unique = true, nullable = false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
#Column(name = "Nome", nullable = false, length = 200)
public String getNome() {
return this.nome;
}
public void setNome(String nome) {
this.nome = nome;
}
#Column(name = "Descricao", nullable = false, length = 200)
public String getDescricao() {
return this.descricao;
}
public void setDescricao(String descricao) {
this.descricao = descricao;
}
}
My Servlet
<?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:jee="http://www.springframework.org/schema/jee"
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.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC #Controller programming model -->
<context:component-scan base-package="com.dtr.oas" />
<context:annotation-config/>
<!-- 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 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="mysqlDS"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://192.168.254.38:3306/7jogos" />
<property name="username" value="root" />
<property name="password" value="6+1Log.pt" />
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="mysqlDS"/>
<property name="persistenceProviderClass" value="org.hibernate.ejb.HibernatePersistence" />
</bean>
<tx:annotation-driven/>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
</beans>
My Persistence
<?xml version="1.0" encoding="UTF-8" ?>
<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_2_0.xsd"
version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="persistenceUnit" transaction-type="RESOURCE_LOCAL">
<!-- shouldn't be valid for java SE per specification, but it works for EclipseLink ... -->
<class>com.dtr.oas.model.Jlocalidades</class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://192.168.254.38:3306/7jogos" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="6+1Log.pt" />
<!-- EclipseLink should create the database schema automatically -->
<property name="eclipselink.ddl-generation" value="create-tables" />
<property name="eclipselink.ddl-generation.output-mode" value="database" />
<property name="eclipselink.logging.level" value="SEVERE"/>
</properties>
</persistence-unit>
My controller that gives the ERROR
package com.dtr.oas.model;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.Persistence;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import com.setelog.model.Jcelulas;
public class JlocalidadesHome implements IJlocalidadesHome {
private static final Log log = LogFactory.getLog(JlocalidadesHome.class);
#Autowired
private SessionFactory sessionFactory;
private Session getCurrentSession() {
return sessionFactory.getCurrentSession();
}
#PersistenceContext
private EntityManager entityManager;
public void persist(Jlocalidades transientInstance) {
log.debug("persisting Jlocalidades instance");
try {
EntityManager entityManager = Persistence.createEntityManagerFactory("persistenceUnit").createEntityManager();
entityManager.persist(transientInstance);
log.debug("persist successful");
} catch (RuntimeException re) {
log.error("persist failed", re);
throw re;
}
}
public void remove(Jlocalidades persistentInstance) {
log.debug("removing Jlocalidades instance");
try {
entityManager.remove(persistentInstance);
log.debug("remove successful");
} catch (RuntimeException re) {
log.error("remove failed", re);
throw re;
}
}
public Jlocalidades merge(Jlocalidades detachedInstance) {
log.debug("merging Jlocalidades instance");
try {
Jlocalidades result = entityManager.merge(detachedInstance);
log.debug("merge successful");
return result;
} catch (RuntimeException re) {
log.error("merge failed", re);
throw re;
}
}
public Jlocalidades findById(Integer id) {
log.debug("getting Jlocalidades instance with id: " + id);
try {
Jlocalidades instance = entityManager.find(Jlocalidades.class, id);
log.debug("get successful");
return instance;
} catch (RuntimeException re) {
log.error("get failed", re);
throw re;
}
}
#Transactional
public List<Jlocalidades> All (){
log.debug("getting all Jlocalidades");
try {
List<Jlocalidades> instance = entityManager.createQuery("SELECT * FROM jlocalidades").getResultList();
log.debug("get successful");
return instance;
} catch (RuntimeException re) {
log.error("get failed", re);
throw re;
}
}
}
You need #Controller on your controller class in order for spring to inject the entityManager into it. Since you want Spring to inject the EntityManager, do not do:
EntityManager entityManager = Persistence.createEntityManagerFactory("persistenceUnit").createEntityManager();
Generally, you will only call Persistence.createEntityManagerFactory() when you are running without a container.
Bootstrap class that is used to obtain an EntityManagerFactory in Java
SE environments.
You can do without persistence.xml by changing your EntityManager configuration:
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="mysqlDS"/>
<property name="packagesToScan" value="YOUR.ENTITY.PKG" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="generatedDdl" value="true" />
<property name="databasePlatform" value="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
</bean>
</property>
</bean>
How is the controller instantiated ? Its need to be a spring managed bean.
You have classpath scanning xml defined in your conf file. But JlocalidadesHome is not annoated with Controller/Component.
By the way, use a controller to take inputs from a request, it should then call service classes ... and the service classes interact with the data layer classes

How to manage persistence using Spring and Hibernate

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.

Too many connections with Spring + MyBatis + MySQL + JDBC

I am trying to work with spring, mybatis and mysql with jdbc. The only small problem I have after some queries, it throws an exception. The DB says: Too many connections.
So what I am trying to do to prevent the too many connection issue is to set up a connection pool. I have tried dbcp and bonecp also but both have the same behaviour. When I reload my page it just keeps loading in the browser and after some debugging it seems it hangs after the 9th or 10th select.
My scenario looks like this:
1: "select * from maincategory"
This query returns around 15 categories. I map the resultset into a List containing MainCategory elements.
Then what I do is I walk through the MainCategory List and get the IDs from each MainCategory and then I do an other select to get their sub categories:
2: "select * from subcategories where id = ${id_from_main_category_actual_row}"
And it seems it hangs after the 9th or 10th subcategory selection.
Here is my transaction manager and sqlsessionfactory configuration:
<beans:bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<beans:property name="dataSource" ref="dataSource" />
</beans:bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<beans:bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<beans:property name="configLocation" value="WEB-INF/spring/myBatis/mybatis.xml" />
<beans:property name="mapperLocations" value="WEB-INF/spring/myBatis/mbmapper-*.xml" />
<beans:property name="dataSource" ref="dataSource" />
</beans:bean>
And here is the configuration for a datasource with dbcp:
<beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<beans:property name="driverClassName" value="com.mysql.jdbc.Driver" />
<beans:property name="url" value="jdbc:mysql://localhost:3306/testdb" />
<beans:property name="username" value="root"/>
<beans:property name="password" value=""/>
</beans:bean>
And my other try was with the bonecp:
<beans:bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
<beans:property name="driverClass" value="com.mysql.jdbc.Driver" />
<beans:property name="jdbcUrl" value="jdbc:mysql://localhost:3306/testdb" />
<beans:property name="username" value="root"/>
<beans:property name="password" value=""/>
<beans:property name="idleConnectionTestPeriodInSeconds" value="30"/>
<beans:property name="idleMaxAgeInMinutes" value="1"/>
<beans:property name="maxConnectionsPerPartition" value="7"/>
<beans:property name="minConnectionsPerPartition" value="7"/>
<beans:property name="partitionCount" value="1"/>
<beans:property name="acquireIncrement" value="1"/>
<beans:property name="acquireRetryAttempts" value="1"/>
<beans:property name="acquireRetryDelayInMs" value="5000"/>
<beans:property name="maxConnectionAgeInSeconds" value="0"/>
<beans:property name="connectionTestStatement" value="SELECT 1"/>
<beans:property name="statementsCacheSize" value="100"/>
<beans:property name="disableConnectionTracking" value="true"/>
</beans:bean>
As you can see I tried many optimization on this with the properties. I think regardless if the method querying for main and their subcategories is a good or wrong practise, its only 10 small queries with some data returned so it should work.
If I use the "org.springframework.jdbc.datasource.DriverManagerDataSource" as the datasource, the db says the "too many connection" after some page refresh, while the tried connection pools just hang after the mentioned amount of query.
UPDATE based on comments:
Here is my detailed code as requested:
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/root-context.xml
/WEB-INF/spring/appServlet/ApplicationContext.xml
/WEB-INF/spring/appServlet/ApplicationContext-security.xml
</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- Spring Security -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
root-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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
ApplicationContext.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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.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.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<beans:bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" />
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<context:annotation-config />
<!-- 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.test.packit" />
<!-- Thymeleaf Template & View Resolver configurations -->
<beans:bean id="templateResolver"
class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
<beans:property name="prefix" value="/WEB-INF/templates/" />
<beans:property name="suffix" value=".html" />
<beans:property name="templateMode" value="HTML5" />
<beans:property name="cacheable" value="false" />
</beans:bean>
<beans:bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine">
<beans:property name="templateResolver" ref="templateResolver" />
<beans:property name="additionalDialects">
<beans:set>
<beans:bean class="org.thymeleaf.extras.springsecurity3.dialect.SpringSecurityDialect" />
</beans:set>
</beans:property>
</beans:bean>
<beans:bean class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
<beans:property name="templateEngine" ref="templateEngine" />
</beans:bean>
<beans:bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<beans:property name="basename" value="localization/general/messages" />
</beans:bean>
<beans:bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
<beans:property name="driverClass" value="com.mysql.jdbc.Driver" />
<beans:property name="jdbcUrl" value="jdbc:mysql://localhost:3306/testdb" />
<beans:property name="username" value="root"/>
<beans:property name="password" value=""/>
<beans:property name="idleConnectionTestPeriodInSeconds" value="30"/>
<beans:property name="idleMaxAgeInMinutes" value="1"/>
<beans:property name="maxConnectionsPerPartition" value="7"/>
<beans:property name="minConnectionsPerPartition" value="7"/>
<beans:property name="partitionCount" value="1"/>
<beans:property name="acquireIncrement" value="1"/>
<beans:property name="acquireRetryAttempts" value="1"/>
<beans:property name="acquireRetryDelayInMs" value="5000"/>
<beans:property name="maxConnectionAgeInSeconds" value="0"/>
<beans:property name="connectionTestStatement" value="SELECT 1"/>
<beans:property name="statementsCacheSize" value="100"/>
<beans:property name="disableConnectionTracking" value="true"/>
</beans:bean>
<!--
<beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<beans:property name="driverClassName" value="com.mysql.jdbc.Driver" />
<beans:property name="url" value="jdbc:mysql://localhost:3306/testdb" />
<beans:property name="username" value="root"/>
<beans:property name="password" value=""/>
</beans:bean>
-->
<!-- Original data source without connection pooling -->
<!--
<beans:bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<beans:property name="driverClassName" value="com.mysql.jdbc.Driver" />
<beans:property name="url" value="jdbc:mysql://localhost:3306/testdb" />
<beans:property name="username" value="root" />
<beans:property name="password" value="" />
</beans:bean>
-->
<beans:bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<beans:property name="dataSource" ref="dataSource" />
</beans:bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<beans:bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<beans:property name="configLocation" value="WEB-INF/spring/myBatis/mybatis.xml" />
<beans:property name="mapperLocations" value="WEB-INF/spring/myBatis/mbmapper-*.xml" />
<beans:property name="dataSource" ref="dataSource" />
</beans:bean>
<!-- MAPPER: ACCOUNT -->
<beans:bean id="accountDao" class="com.test.packit.dao.AccountDao">
<beans:property name="sessionFactory" ref="sqlSessionFactory" />
</beans:bean>
<beans:bean id="accountService" class="com.test.packit.service.AccountService">
<beans:property name="accountDao" ref="accountDao" />
</beans:bean>
<!-- MAPPER: MAIN_CATEGORY -->
<beans:bean id="mainCategoryDao" class="com.test.packit.dao.MainCategoryDao">
<beans:property name="sessionFactory" ref="sqlSessionFactory" />
</beans:bean>
<beans:bean id="mainCategoryService" class="com.test.packit.service.MainCategoryService">
<beans:property name="mainCategoryDao" ref="mainCategoryDao" />
</beans:bean>
<!-- MAPPER: SUB_CATEGORY -->
<beans:bean id="subCategoryDao" class="com.test.packit.dao.SubCategoryDao">
<beans:property name="sessionFactory" ref="sqlSessionFactory" />
</beans:bean>
<beans:bean id="subCategoryService" class="com.test.packit.service.SubCategoryService">
<beans:property name="subCategoryDao" ref="subCategoryDao" />
</beans:bean>
</beans:beans>
ApplicationContext-security.xml:
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="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-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/admin**" access="ROLE_ADMIN" />
<intercept-url pattern="/admin.jsp" access="ROLE_ADMIN" />
<intercept-url pattern="/user.jsp" access="ROLE_USER" />
<session-management session-fixation-protection="none">
<concurrency-control />
</session-management>
<form-login
login-page="/login"
login-processing-url="/letmein"
default-target-url="/"
authentication-failure-url="/login-error"
username-parameter="bm_username"
password-parameter="bm_password" />
<logout logout-url="/logout"/>
<!-- enable csrf protection -->
<csrf/>
</http>
<authentication-manager>
<authentication-provider>
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query="SELECT username, password, enabled
FROM bm_users
WHERE username=?"
authorities-by-username-query="SELECT username, role
FROM bm_roles
WHERE username=?" />
<password-encoder hash="bcrypt"/>
</authentication-provider>
</authentication-manager>
</beans:beans>
mybatis.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
</configuration>
mbmapper-mainCategory-mapper.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="maincategory">
<cache type="org.mybatis.caches.hazelcast.LoggingHazelcastCache"/>
<select id="getAllMainCategories" resultType="list" resultMap="mainCategoryMap.mainCategoryResultMap">
SELECT * FROM packit.bm_maincategory;
</select>
</mapper>
mbmapper-mainCategory-resultMap.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mainCategoryMap">
<resultMap type="com.test.packit.model.MainCategory" id="mainCategoryResultMap">
<id property="id" column="id"/>
<result property="name" column="name"/>
</resultMap>
</mapper>
mbmapper-subCategory-mapper.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="subcategory">
<cache type="org.mybatis.caches.hazelcast.LoggingHazelcastCache"/>
<select id="getAllSubCategoriesForMainCategory" parameterType="int" resultType="list" resultMap="subCategoryMap.subCategoryResultMap">
SELECT * FROM packit.bm_subcategory WHERE maincategory_id = #{id};
</select>
</mapper>
mbmapper-subCategory-resultMap.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="subCategoryMap">
<resultMap type="com.test.packit.model.SubCategory" id="subCategoryResultMap">
<id property="id" column="id"/>
<result property="name" column="name"/>
</resultMap>
</mapper>
MainCategory.java:
package com.test.packit.model;
import java.io.Serializable;
import java.util.List;
public class MainCategory implements Serializable {
private static final long serialVersionUID = -7970848646314840509L;
private Integer id;
private String name;
private List<SubCategory> subCategories;
public List<SubCategory> getSubCategories() {
return subCategories;
}
public void setSubCategories(List<SubCategory> subCategories) {
this.subCategories = subCategories;
}
public MainCategory() {
super();
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
MainCategoryDao.java:
package com.test.packit.dao;
import java.util.List;
import javax.annotation.Resource;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.stereotype.Repository;
import com.test.packit.model.MainCategory;
#Repository
public class MainCategoryDao {
#Resource
private SqlSessionFactory sessionFactory;
public SqlSessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(SqlSessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
#SuppressWarnings("unchecked")
public List<MainCategory> getAllMainCategories(){
SqlSession session = sessionFactory.openSession();
List<MainCategory> mainCategoriesFromDb = (List<MainCategory>)(List<?>) session.selectList("maincategory.getAllMainCategories");
return mainCategoriesFromDb;
}
}
MainCategoryService.java:
package com.test.packit.service;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Repository;
import com.test.packit.dao.MainCategoryDao;
import com.test.packit.model.MainCategory;
#Repository
public class MainCategoryService {
#Resource
private MainCategoryDao mainCategoryDao;
public List<MainCategory> getAllCategories() {
return mainCategoryDao.getAllMainCategories();
}
public MainCategoryDao getMainCategoryDao() {
return mainCategoryDao;
}
public void setMainCategoryDao(MainCategoryDao mainCategoryDao) {
this.mainCategoryDao = mainCategoryDao;
}
}
SubCategory.java:
package com.test.packit.model;
import java.io.Serializable;
public class SubCategory implements Serializable {
private static final long serialVersionUID = -7970848646314840509L;
private Integer id;
private Integer mainCategoryId;
private String name;
public Integer getMainCategoryId() {
return mainCategoryId;
}
public void setMainCategoryId(Integer mainCategoryId) {
this.mainCategoryId = mainCategoryId;
}
public SubCategory() {
super();
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
SubCategoryDao.java:
package com.test.packit.dao;
import java.util.List;
import javax.annotation.Resource;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.stereotype.Repository;
import com.test.packit.model.SubCategory;
#Repository
public class SubCategoryDao {
#Resource
private SqlSessionFactory sessionFactory;
public SqlSessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(SqlSessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
#SuppressWarnings("unchecked")
public List<SubCategory> getAllSubCategoriesForMainCategory(int id){
SqlSession session = sessionFactory.openSession();
List<SubCategory> subCategoriesFromDb = (List<SubCategory>)(List<?>) session.selectList("subcategory.getAllSubCategoriesForMainCategory", id);
return subCategoriesFromDb;
}
}
SubCategoryService.java:
package com.test.packit.dao;
import java.util.List;
import javax.annotation.Resource;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.stereotype.Repository;
import com.test.packit.model.SubCategory;
#Repository
public class SubCategoryDao {
#Resource
private SqlSessionFactory sessionFactory;
public SqlSessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(SqlSessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
#SuppressWarnings("unchecked")
public List<SubCategory> getAllSubCategoriesForMainCategory(int id){
SqlSession session = sessionFactory.openSession();
List<SubCategory> subCategoriesFromDb = (List<SubCategory>)(List<?>) session.selectList("subcategory.getAllSubCategoriesForMainCategory", id);
return subCategoriesFromDb;
}
}
HomeController.java:
package com.test.packit;
import com.test.packit.authentication.AuthenticatorController;
import com.test.packit.model.MainCategory;
import com.test.packit.model.SubCategory;
import com.test.packit.service.MainCategoryService;
import com.test.packit.service.SubCategoryService;
import java.util.List;
import java.util.Locale;
import javax.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
#Controller
public class HomeController {
#Resource
private MainCategoryService mainCategoryService;
private List<MainCategory> mainCategories;
#Resource
private SubCategoryService subCategoryService;
private List<SubCategory> subCategories;
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
#RequestMapping(value = "/", method = RequestMethod.GET)
public String index(Locale locale, Model model) {
// Get all main categories
mainCategories = mainCategoryService.getAllCategories();
for(MainCategory mainCategory : mainCategories) {
logger.info("Main Category: {}", mainCategory.getName());
// Get all sub categories
subCategories = subCategoryService.getAllSubCategoriesForMainCategory(mainCategory.getId());
mainCategory.setSubCategories(subCategories);
for(SubCategory subCategory : subCategories) {
logger.info("\t\t- {}", subCategory.getName());
}
}
model.addAttribute("mainCategories", mainCategories);
return "index";
}
}
Any suggestion are very welcomed.
1. When creating SqlSessions manually you have to make sure that you close them after use.
Look for all places where you are opening a SqlSession:
SqlSession session = sessionFactory.openSession();
Make sure that you're closing the session after use. You should do that in try-finally block, like below:
SqlSession session = sqlSessionFactory.openSession();
try {
// following 3 lines pseudocode for "doing some work"
session.insert(...);
session.update(...);
session.delete(...);
session.commit();
} finally {
session.close();
}
More information on how to handle MyBatis SqlSessions can be found here: http://mybatis.github.io/mybatis-3/java-api.html#sqlSessions
2. You can use MyBatis-Spring to create and manage the lifecycle of SqlSessions.
Instead of injecting DAO's with SqlSessionFactory, you can ask spring to inject the SqlSessions directly. When you do this, Spring will manage the SqlSessions for you, so you will not have to open/close sessions by yourself.
More information how to do this is here: http://mybatis.github.io/spring/sqlsession.html

Categories