Here is my implementation in summary
1) all DAOs implemented using HibernateDAO support/ @Transational annotation is only used in Service layer
2) Use MySQL / HibernateTransactionManager
3) Test using main(String args[]) method (do transactions work using this method? )
Transactions does not get rollbacked and invalid entried can be seen in the database.
What am I doing wrong here?
Detailed information is given below.
1) I have configured transactions using @Transactional annotation in service layer as:
@Transactional(readOnly=false, rollbackFor={DuplicateEmailException.class,DuplicateLoginIdException.class,IdentityException.class},propagation=Propagation.REQUIRES_NEW)
public void createUserProfile(UserProfile profile)
throws DuplicateEmailException, DuplicateLoginIdException,
IdentityException {
//Accessing DAO (implemented using HibernateDAOSupport)
identityDAO.createPrincipal(profile.getSecurityPrincipal());
try {
//Accessing DAO
userProfileDAO.createUserProfile(profile);
} catch (RuntimeException e) {
throw new IdentityException("UseProfile create Error", e);
}
}
2) My Transation Manager configuration / datasource is as follows :
<bean id="dataSource"
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/ibmdusermgmt" />
<property name="username" value="root" />
<property name="password" value="root" />
<property name="defaultAutoCommit" value="false"/>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mappingLocations"
value="classpath*:hibernate/*.hbm.xml" />
<property name="hibernateProperties">
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</prop>
<prop key="hibernate.query.substitutions">
true=1 false=0
</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.use_outer_join">false</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
3) Test using main() method as follows :
public static void main(String[] args) {
ApplicationContext cnt=new ClassPathXmlApplicationContext("testAppContext.xml");
IUserProfileService upServ=(IUserProfileService)cnt.getBean("ibmdUserProfileService");
UserProfile up=UserManagementFactory.createProfile("testlogin");//
up.setAddress("address");
up.setCompany("company");
up.setTelephone("94963842");
up.getSecurityPrincipal().setEmail("security@email.com");
up.getSecurityPrincipal().setName("Full Name");
up.getSecurityPrincipal().setPassword("password");
up.getSecurityPrincipal().setSecretQuestion(new SecretQuestion("Question", "Answer"));
try {
upServ.createUserProfile(up);
} catch(Exception e){
e.printStackTrace();
}
As far as I know, MySQL’s default storage engine MyISAM does not support transactions.
In order to get transactions working, you’ll have to switch your storage engine for those tables to InnoDB. You may also want to use Hibernate’s MySQLInnodDBDialect if you generate your tables (
hdm2ddl) from your mappings:As mentioned by @gid, it’s not a requirement for transactions though.