I have implemented transactional rollback in the following way. This code worked well when I tried to implement the same on HSql DB and SQL Server. But the same transactional rollback is not working when implemented on MySQL DB. What could be the possible solution for rolling back the transaction in case of MySQL?
Here is my code -
xml file-> implement.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-3.0.xsd ">
<!-- Initialization for data source -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://(mydb details)"/>
<property name="username" value="(my db username)"/>
<property name="password" value="(my db password)"/>
</bean>
<!-- Initialization for TransactionManager -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- Definition for studentJDBCTemplate bean -->
<bean id="implementOnlyTransactions" class="Transactions.implementOnlyTransactions">
<property name="dataSource" ref="dataSource" />
<property name="transactionManager" ref="transactionManager" />
</bean>
</beans>
implementOnlyTransactions.java->
package Transactions;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionException;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;
public class implementOnlyTransactions {
private DataSource dataSource;
private JdbcTemplate jdbcTemplateObject;
private PlatformTransactionManager transactionManager;
public void setDataSource(DataSource dataSource) throws SQLException {
this.dataSource = dataSource;
this.jdbcTemplateObject = new JdbcTemplate(dataSource);
}
public void setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
public void create(Integer id, String name) throws Exception {
TransactionDefinition def = new DefaultTransactionDefinition();
TransactionStatus status = transactionManager.getTransaction(def);
try {
String SQL1 = "insert into Student (ID,Name) values (?, ?)";
int r = jdbcTemplateObject.update(SQL1, id, name);
System.out.println("Inserted Name = " + name + ", ID = " + id);
if(r>0){
transactionManager.rollback(status);
}
transactionManager.commit(status);
} catch (DataAccessException e) {
System.out.println("Error in creating record, rolling back");
//transactionManager.rollback(status);
throw e;
}
}
}
MainClass.java -->
package Transactions;
import java.sql.SQLException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainClass {
public static void main(String[] args) throws Exception {
ApplicationContext context = new ClassPathXmlApplicationContext("xmlFiles/implement.xml");
implementOnlyTransactions implemt =
(implementOnlyTransactions)context.getBean("implementOnlyTransactions");
try {
implemt.create(36,"bye2");
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Related
I am trying to learn Spring MVC.I have a registration form which I am trying to persist. I have MySQL as backend.I have a test java application which is able to connect to MySQL and insert into table. But the same thing does not work for the web application. I am using Eclipse as IDE and Maven for build and tomcat as webserver.
Datasource file
<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-2.5.xsd">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/chorechart" />
<property name="username" value="username" />
<property name="password" value="password*" />
</bean>
DAO
package com.chorechart.dao.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import javax.sql.DataSource;
import org.springframework.stereotype.Service;
import com.chorechart.dao.RegisterDAO;
import com.chorechart.model.Register;
#Service("registerDAO")
public class JdbcRegisterDAO implements RegisterDAO{
private DataSource dataSource;
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
#Override
public void insertUser(Register registerUser) {
String sql = "Insert into register"+"
(FirstName,LastName,Email_username,password)"
+ "values(?,?,?,?)";
);
try {
System.out.println("DataSourrce"+dataSource);
Connection conn = dataSource.getConnection();
System.out.println("coonection"+conn);
PreparedStatement ps= conn.prepareStatement(sql);
ps.setString(1,registerUser.getFirstName());
ps.setString(2,registerUser.getLastName());
ps.setString(3, registerUser.getEmail_username());
ps.setString(4, registerUser.getPassword());
int x = ps.executeUpdate();
}catch(Exception ex) {
System.out.print("JDBCRegisterDao");
ex.printStackTrace();
}
}
}
#Override
public Register findUser(String userName, String userPwd) {
// TODO Auto-generated method stub
return null;
}
public DataSource getDataSource() {
return dataSource;
}
So I implemented jdbc in my java programm. The "old-fashion" way works fluently and i get access to the database.
Now I wanted to refactor my code to Spring JDBC, because it offers more opportunities. But somehow my injection from beans.xml does not work. The dataSource is always null, therefore I can't execute any SQL Querys... because it is always null.
Beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${db.driverClassName}"></property>
<property name="url" value="${db.url}"></property>
</bean>
<bean id="userService" class="beco.webservice.service.impl.UserServiceImpl">
<property name="userDAO" ref="userDAO"></property>
</bean>
<bean id="userDAO" class="beco.webservice.dao.impl.UserDAOImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>database.properties</value>
</list>
</property>
</bean>
</beans>
database.properties
db.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
db.url=jdbc:sqlserver://XX-XXXXXX\\XXXXX;databaseName=BBSupportQA;integratedSecurity=true
UserDataAccessObject.java
import java.util.List;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import beco.webservice.dao.UserDAO;
import beco.webservice.model.User;
public class UserDAOImpl implements UserDAO {
private DataSource dataSource;
private JdbcTemplate jdbcTemplate;
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
#Override
public void createUser(User user) {
String SQL = "INSERT INTO dbo.BCO_Person(USER_ID, Email, Nickname) VALUES (?,?,?)";
int update = jdbcTemplate.update(SQL, user.getUserId(), user.getEmail(), user.getNickname());
if(update>0)
System.out.print("User is created...");
}
[...]
}
So I always get a Nullpointer and i debugged it and saw that DataSource / JDBCTemplate is always null.
If i use the old fashion way:
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
conn = DriverManager.getConnection("jdbc:sqlserver:sqlserver://XX-XXXXXX\\XXXXX;databaseName=BBSupportQA;integratedSecurity=true");
System.out.println(LOG_TAG + "Database successfully connected.");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
It works without any problems. What am I doing wrong? Is the url schema in the Spring properties different from the normal jdbc? I have no explanation for this.
This is the applicationContext.xml file which i placed in the src/main/resources folder.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- Employee DB data source. -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="${jdbc.driverClassName}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="maxPoolSize" value="${jdbc.maxPoolSize}" />
<property name="minPoolSize" value="${jdbc.minPoolSize}" />
<property name="maxStatements" value="${jdbc.maxStatements}" />
<property name="testConnectionOnCheckout" value="${jdbc.testConnection}" />
</bean>
<bean id="Utilities" class="com.pooling.test.Utilities">
</bean>
<context:component-scan base-package="com.pooling.controllers">
</context:component-scan>
This is the jdbc.properties file which i placed in the src/main/resources folder.
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/books
jdbc.username=root
jdbc.password=admin
jdbc.maxPoolSize=50
jdbc.minPoolSize=10
jdbc.maxStatements=10
jdbc.testConnection=true
jdbc.unreturnedConnectionTimeout=240
jdbc.debugUnreturnedConnectionStackTraces=true
This is the Utilities class that contains the logic that i wish to perform
package com.pooling.test;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import com.jolbox.bonecp.BoneCP;
public class Utilities {
private final String CLASS_NAME = "Utilities";
#Autowired
private DataSource datasource;
public String createListofCategories()
{
String METHOD_NAME = "createListofCategories()";
/*//===========================================================================
TransactionDefinition mDefinition = new DefaultTransactionDefinition();
TransactionStatus mStatus = mTransactionManager.getTransaction(mDefinition);
//=========================================================================== */
String listOfCategories = "";
String sequel = "select distinct category_id, key_desc from book_resource_view, keywords_record_table";
sequel = sequel + " where keyword_key=category_id and category_id > 1 ";
sequel = sequel + " order by key_desc";
Connection connection = null;
ResultSet results = null;
Statement state = null;
int categoryID = 0;
String categoryDesc = "";
int numRows = 0;
try
{
connection = datasource.getConnection();
state = connection.createStatement();
results = state.executeQuery(sequel);
results.last();
numRows = results.getRow();
//======================================
results.beforeFirst();
for(int i=0; results.next(); i++){
listOfCategories = listOfCategories + "<td><ul id=\"category_list\">";
for(int j=0; j<16; j++){
categoryID = results.getInt("category_id");
categoryDesc = results.getString("key_desc");
listOfCategories = listOfCategories + "<li>"+categoryDesc+"</li>";
if(!results.next()){
break;
}
}
results.previous();
listOfCategories = listOfCategories + "</ul></td>";
}
listOfCategories = "<tr>"+listOfCategories+"</tr>";
}
catch (SQLException localSQLException)
{
try
{
results.close();
state.close();
connection.close();
}
catch (SQLException localSQLException1)
{
}
}
finally
{
try {
results.close();
state.close();
connection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return listOfCategories;
}
This is the controller code that i wish to call from the browser.
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.pooling.test.ConnectionManager;
import com.pooling.test.Utilities;
#Controller
public class TestController {
#RequestMapping(value="/testing",method=RequestMethod.GET)
public #ResponseBody String getCategories(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Utilities utilities = (Utilities) context.getBean("Utilities");
return utilities.createListofCategories();
}
}
PROBLEM: the problem is that the pool gets initialized properly but when i keep executing the same controller request again and again the connection pool keeps on creating connections until the server gives "too many connections" error
I think the problem lies in the fact that you create a new ApplicationContext everytime the getCategories() method is called.
As #Chrylis already mentioned, you don't need to call context.getBean().
Replace the two lines from ApplicationContext to context.getBean() to #Autowired Utilities utilities. Just like you did with datasource in your Utilities class.
i had earlier created the spring framework, then replaced with the database connection, but there is problem in creating the beans.
also receiving the below error during the deployment.
DEFAULT=C:\Users\gopc\Documents\NetBeansProjects\HelloSpringJDBC\build\web&name=HelloSpringJDBC&contextroot=/HelloSpringJDBC&force=true
failed on GlassFish Server 3.1.2 Error occurred during deployment:
Exception while loading the app : java.lang.IllegalStateException:
ContainerBase.addChild: start: org.apache.catalina.LifecycleException:
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'productManager' defined in ServletContext
resource [/WEB-INF/applicationContext.xml]: Error setting property
values; nested exception is
org.springframework.beans.NotWritablePropertyException: Invalid
property 'productDao' of bean class [SimpleProductManager]: Bean
property 'productDao' is not writable or has an invalid setter method.
Does the parameter type of the setter match the return type of the
getter?. Please see server.log for more details.
C:\Users\gopc\Documents\NetBeansProjects\HelloSpringJDBC\nbproject\build-impl.xml:1029:
The module has not been deployed. See the server log for details.
Source
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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
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/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<bean id="externalDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" scope="singleton" destroy-method="close">
<property name="driverClassName" value="sun.jdbc.odbc.JdbcOdbcDriver"/>
<property name="url" value="jdbc:odbc:;DRIVER=Microsoft Access Driver (*.mdb, *.accdb);DBQ=C://Users//gopc//Documents//odbc_sql.accdb"/>
<property name="username" value=""/>
<property name="password" value=""/>
</bean>
<bean id="productManager" class="SimpleProductManager">
<property name="productDao" ref="productDao"/>
</bean>
<bean id="productDao" class="JdbcProductDao">
<property name="dataSource" ref="externalDataSource"/>
</bean>
</beans>
spirngapp-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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
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/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="messages"/>
</bean>
<bean name="/hello.htm" class="HelloController">
<property name="productManager" ref="productManager"/>
</bean>
<!-- we can prefix="/"
http://localhost:8080/HelloSpring/hello.htm
specify the path in modelview from the controller
OR
Decouple the view from the controller
prefix="/WEB-INF/jsp/"
-->
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
<property name="defaultLocale" value="en_US"/>
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:viewClass="org.springframework.web.servlet.view.JstlView"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp" />
</beans>
JdbcProductDao.java
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport;
public class JdbcProductDao extends SimpleJdbcDaoSupport implements ProductDao {
protected final Log logger = LogFactory.getLog(getClass());
public List<Product> getProductList() {
logger.info("Getting products!");
List<Product> products = getSimpleJdbcTemplate().query(
"select id, description, price from products",
new ProductMapper());
return products;
}
public void saveProduct(Product prod) {
logger.info("Saving product: " + prod.getDescription());
int count = getSimpleJdbcTemplate().update(
"update products set description = :description, price = :price where id = :id",
new MapSqlParameterSource().addValue("description", prod.getDescription())
.addValue("price", prod.getPrice())
.addValue("id", prod.getId()));
logger.info("Rows affected: " + count);
}
private static class ProductMapper implements ParameterizedRowMapper<Product> {
public Product mapRow(ResultSet rs, int rowNum) throws SQLException {
Product prod = new Product();
prod.setId(rs.getInt("id"));
prod.setDescription(rs.getString("description"));
prod.setPrice(new Double(rs.getDouble("price")));
return prod;
}
}
}
SimpleProductManager.java
import java.util.List;
import java.util.ArrayList;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class SimpleProductManager implements ProductManager {
protected final Log logger = LogFactory.getLog(getClass());
private ProductDao productDao;
public List<Product> getProductDao() {
//throw new UnsupportedOperationException();
return productDao.getProductList();
}
public void increasePrice(int percentage) {
//throw new UnsupportedOperationException();
List <Product> products = productDao.getProductList();
for (Product product : products) {
double newPrice = product.getPrice() * (100 + percentage)/100;
product.setPrice(newPrice);
productDao.saveProduct(product);
}
}
public void setProductDao(ProductDao productDao) {
//throw new UnsupportedOperationException();
logger.info("inside the setProducts in SimpleProductManager");
this.productDao = productDao;
}
}
HelloController.java
import java.util.Date;
import java.util.Map;
import java.util.HashMap;
import org.springframework.web.servlet.mvc.Controller;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.IOException;
public class HelloController implements Controller {
private ProductManager productManager;
protected final Log logger = LogFactory.getLog(getClass());
/*
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
logger.info("Returning hello view");
String now = ( new Date().toString());
logger.info("time now:"+ now);
//return new ModelAndView("hello");
//return new ModelAndView("WEB-INF/jsp/hello","now",now);
//decouple the view from the controller
return new ModelAndView("hello","now",now);
}
*/
//Writing some business logic in the controller
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
String now = (new java.util.Date()).toString();
logger.info("returning hello view with " + now);
Map<String, Object> myModel = new HashMap<String, Object>();
myModel.put("now", now);
myModel.put("products", this.productManager.getProductDao());
return new ModelAndView("hello", "model", myModel);
}
public void setProductManager(ProductManager productManager)
{
this.productManager = productManager;
}
}
hey the problem got resovled, after i had modified, the following..
1) applicationContext with mapping for the bean "productManager" with ref productDao.
2) ProductManager interface with new method call getProducts(), then implemenent in the SimpleProductManager and which call the ProductDao.getProducts(), where the sql query is being defined.
I'm trying to convert my very small app to Spring 3.2 and Hibernate 4, but I can't get it to run properly with sessions. Some info below this paragraph, but ultimately the sessionFactory is always null everytime it gets to the DAO and I can't figure out why.
Comparing the console to Hibernate 3, Hibernate 3 shows this upon startup:Nov 23, 2012 10:51:52 PM org.springframework.orm.hibernate3.LocalSessionFactoryBean buildSessionFactory
INFO: Building new Hibernate SessionFactory
Stack trace:
java.lang.NullPointerException
dao.CSSDAOImpl.selectAllCSS(CSSDAOImpl.java:21)
hibernate-cfg.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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<bean id="myDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.apache.derby.jdbc.EmbeddedDriver"></property>
<property name="url" value="jdbc:derby:C:\Users\Steven\MyDB"></property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="packagesToScan" value="net.form" />
<property name="dataSource" ref="myDataSource"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.DerbyTenSevenDialect
</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="annotatedClasses">
<list>
<value>net.form.StyleChooser</value>
</list>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="CSSDAO" class="dao.CSSDAOImpl">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>
DAO:
package dao;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import net.form.StyleChooser;
public class CSSDAOImpl implements CSSDAO {
private SessionFactory sessionFactory;
#Autowired
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
#Transactional
public List selectAllCSS() {
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
List l = session.createCriteria(StyleChooser.class).list();
session.flush();
tx.commit();
return l;
}
#Transactional
public StyleChooser selectCSSById(Integer ID) {
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
StyleChooser sc = (StyleChooser) session.get(StyleChooser.class, ID);
session.flush();
tx.commit();
return sc;
}
#Transactional
public Integer insertCSS(StyleChooser insertCSS) {
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Integer id = (Integer) session.save(insertCSS);
session.flush();
tx.commit();
return id;
}
#Transactional
public void deleteCSS(Integer CSSId) {
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
StyleChooser sc = (StyleChooser) session.get(StyleChooser.class, CSSId);
session.delete(sc);
session.flush();
tx.commit();
}
#Transactional
public void updateCSS(StyleChooser cssWithNewValues) {
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
session.update(cssWithNewValues);
session.flush();
tx.commit();
}
}
Accessing DAO...
package net.controllers;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import net.form.StyleChooser;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
import dao.CSSDAOImpl;
#Controller
#RequestMapping("/stylechoosertable.html")
public class IndexController extends MultiActionController {
Resource resource = new FileSystemResource(
"C:/Users/Steven/Desktop/Programming/workspace/CSSGeneratorHibernate4/WebContent/WEB-INF/hibernate.cfg.xml");
BeanFactory beanFactory = new XmlBeanFactory(resource);
CSSDAOImpl dao = (CSSDAOImpl) beanFactory.getBean("CSSDAO");
#RequestMapping(method = RequestMethod.GET)
public ModelAndView showIndex(HttpServletRequest request) throws Exception {
List<StyleChooser> styleChooser = dao.selectAllCSS();
return new ModelAndView("stylechoosertable", "styleChooser", styleChooser);
}
}
In your Spring configuration file make the following change:
<bean id="CSSDAO" class="dao.CSSDAOImpl">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
Now, in CSSDAOImpl remove all the static modifiers:
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
That should fix the NPE!
To keep things nice and clean you should use #Transactional-Annotation in all methods and not open the sessions manually but always with sessionFactory.getCurrentSession(). ...
I suppose you wanted to to do it that way anyways since you use tx: annotation-driven and have already imported the annotation.
Alternatively to Muel's answer, you could also use a #Autowired-Annotation on the setSessionFactory()-method.