Hi Marten,
Thank you so much for the response. I think I understood what I needed to do.
However I am not sure.
I wrote two versions of this same program. One works and one doesn't work.
The difference being @Transactional is for updateByPrimaryKey() method in UserDAOImpl in the version that works. In the version that doesn't work, I put the @Transactional in doTransaction() method and removed the @Transactional from UserDAOImpl. doTransaction() in worker class calls the UserDAOImpl.
Could you please explain why the other one is not working.
The version that doesn't work:
applicationContext.xml:
-------------------------
Code:
<?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:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-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/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<tx:annotation-driven/>
<context:property-placeholder location="com/sampleibatisproj/maps/jdbc.properties"/>
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName"
value="${jdbc.driverClassName}" />
<property name="url"
value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="sqlMap"
class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation">
<value>classpath:com/sampleibatisproj/maps/SqlMapConfig.xml</value>
</property>
<property name="dataSource" ref="dataSource" />
<property name="useTransactionAwareDataSource" value="true"/>
</bean>
<bean id="userDAOImpl"
class="com.sampleibatisproj.dao.UserDAOImpl">
<property name="sqlMapClient" ref="sqlMap" />
<property name="dataSource"><ref local="dataSource"/></property>
</bean>
<bean id="workerBean" class="Worker">
<property name="userDAO" ref="userDAOImpl" />
</bean>
</beans>
Worker Class:
----------------
Code:
public class Worker {
private UserDAO userDAO;
public Worker(){
}
@Transactional
public void doTransaction(){
try
{
User user = (User)userDAO.selectByPrimaryKey(2);
System.out.println(user.getEmail() + " " + user.getFirstName() + " " + user.getLastName());
user.setId(2);
user.setEmail("abcde@gmail.com");
user.setFirstName("nihu");
userDAO.updateByPrimaryKey(user);
throw new DataAccessException("abce") {};
}
catch(Exception e){
System.out.println(e.getMessage());
e.printStackTrace();
}
}
public UserDAO getUserDAO() {
return userDAO;
}
public void setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
}
}
Main class:
---------------
Code:
public class Main {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("com/sampleibatisproj/maps/applicationContext.xml");
try
{
System.out.println("Classpath loaded");
System.out.println(" ");
Worker worker = (Worker) ctx.getBean("workerBean");
worker.doTransaction();
}
catch(Exception e){
System.out.println(e.getMessage());
e.printStackTrace();
}
}
public Main() {
super();
}
}
UserDAOImpl Class:
----------------------
Code:
public class UserDAOImpl extends SqlMapClientDaoSupport implements UserDAO {
public UserDAOImpl() {
super();
}
public void updateByPrimaryKey(User record) {
int rows = getSqlMapClientTemplate().update(
"user.abatorgenerated_updateByPrimaryKey", record);
}
}
The above version in which I use worker class doesn't work.
How ever the version below is working fine.
The version that works :
applicationContext.xml:
-------------------------
Code:
<?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:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-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/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<beans>
<tx:annotation-driven/>
<context:property-placeholder location="com/sampleibatisproj/maps/jdbc.properties"/>
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName"
value="${jdbc.driverClassName}" />
<property name="url"
value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="sqlMap"
class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation">
<value>classpath:com/sampleibatisproj/maps/SqlMapConfig.xml</value>
</property>
<property name="dataSource" ref="dataSource" />
<property name="useTransactionAwareDataSource" value="true"/>
</bean>
<bean id="userDAOImpl"
class="com.sampleibatisproj.dao.UserDAOImpl">
<property name="sqlMapClient" ref="sqlMap" />
<property name="dataSource"><ref local="dataSource"/></property>
</bean>
</beans>
Main Class:
------------------
Code:
public class Main {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("com/sampleibatisproj/maps/applicationContext.xml");
try
{
System.out.println("Classpath loaded");
System.out.println(" ");
UserDAO userDAO = (UserDAO) ctx.getBean("userDAOImpl");
User user = (User)userDAO.selectByPrimaryKey(2);
System.out.println(user.getEmail() + " " + user.getFirstName() + " " + user.getLastName());
user.setId(2);
user.setEmail("niharika@gmail.com");
user.setFirstName("nihuvtasak");
userDAO.updateByPrimaryKey(user);
}
catch(Exception e){
System.out.println(e.getMessage());
e.printStackTrace();
}
}
public Main() {
super();
}
}
Code:
UserDAOImpl Class:
--------------------
public class UserDAOImpl extends SqlMapClientDaoSupport implements UserDAO {
public UserDAOImpl() {
super();
}
@Transactional
public void updateByPrimaryKey(User record) {
int rows = getSqlMapClientTemplate().update(
"user.abatorgenerated_updateByPrimaryKey", record);
throw new DataAccessException("abce") {};
}
}
I have some other queries as well.
If I understand your statements correctly - you are telling that we need to load the application context only once in the project.
1. How do we usually do that in real time scenario.
2. Do we have to get the application context as a singleton object?
3. What is the best way to load application Context.
Could you please answer my queries?
Thanks,
Harish