aspose file tools*
The moose likes Spring and the fly likes Spring-Hibernate transaction management Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Soft Skills this week in the Jobs Discussion forum!
JavaRanch » Java Forums » Frameworks » Spring
Bookmark "Spring-Hibernate transaction management" Watch "Spring-Hibernate transaction management" New topic
Author

Spring-Hibernate transaction management

Kavita Shivani
Ranch Hand

Joined: Aug 14, 2009
Posts: 45
Hi all,
I am doing a small project using Spring framework. I am following a sample project that I found on the internet and using that archtecture. Following the sample project I created a transactionManager bean as shown in the below code snippet. But I am getting an exception. The xml and exception details are shown below. Also I dont know the meaning of the props PROPAGATION_REQUIRED. what it does and how the transaction is handled because of using all these beans. Please explain or give links to any article that will help me.

XML Details


Exception

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loginService' defined in ServletContext resource [/WEB-INF/postsales-services.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'transactionManager' of bean class [com.postsales.service.impl.LoginServiceImpl]: Bean property 'transactionManager' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
Caused by:
org.springframework.beans.NotWritablePropertyException: Invalid property 'transactionManager' of bean class [com.postsales.service.impl.LoginServiceImpl]: Bean property 'transactionManager' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?


Many thanks,
Kavitha.
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17260
    
    6

Can you post more of your xml.

Where is the sessionFactory xml? Where is the hibernateuserDao? Why do you need to have a bean of type TransactionProxyFactoryBean.

I would mostly question the tutorial/sample that you are following

We only need

dataSource
sessionFactory which needs the datasource
transactionManager which needs the sessionfactory

Mark


Perfect World Programming, LLC - Two Laptop Bag - Tube Organizer
How to Ask Questions the Smart Way FAQ
Kavita Shivani
Ranch Hand

Joined: Aug 14, 2009
Posts: 45
I did reply , but somehow my reply doesnt appear on the page, so pasting it again,

I had skipped the <parameter name="target"> part because of which I got this exception. But even though its working fine, I believe I am not able to best utilize the spring framwork. I do understand the controller and VOs but I dont understand transaction management part of the xml. I am doing something its working fine for me, but I dont know what I am doing and why? I would much appriciate if you could help me explain how can I use the transaction manager to best suit my project. I have a use case "Create Invoice" where I have to update two tables. The invoice table, generate invoice number, then go and update the sales table add all the items from the UI for that invoice and give reference of this invoice number to each entry in the sales table.
Now I believe I have done some transaction handling using the spring-hibernate transaction management. But not sure if thats the best way of doing it. Also while I was researching on this, I found a link which was handy. I have pasted the link as well in the end. Your comments and suggestions about my xml are welcome.
My project is postsales and the tutorial project is accountmanagement
Following is the listing


postsales-service.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE beans PUBLIC "-SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- application context -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close" singleton="true">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/storeoperations" />
<property name="username" value="Guest" />
<property name="password" value="welcome" />
</bean>
<!-- Hibernate Session and xml mapping -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
singleton="true">
<property name="dataSource" ref="dataSource" />
<property name="mappingResources">
<list>
<value>conf/user.hbm.xml</value>
<value>conf/product.hbm.xml</value>
<value>conf/invoice.hbm.xml</value>
<!-- <value>conf/salesdetails.hbm.xml</value> -->
<value>conf/delSchedule.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
</value>
</property>
</bean>

<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager"
singleton="true">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="abstractService"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
abstract="true">
<property name="transactionManager" ref="transactionManager" />
<property name="transactionAttributes">
<props>
<prop key="insert">PROPAGATION_REQUIRED</prop>
<prop key="update">PROPAGATION_REQUIRED</prop>
<prop key="delete">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED</prop>

</props>
</property>
</bean>
<!-- Dao Implementation -->

<!-- User -->
<bean id="hibernateuserDao" class="com.postsales.domain.dao.hibernate.HibernateUserDao"
singleton="true">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- Invoice -->
<bean id="hibernateInvoiceDao" class="com.postsales.domain.dao.hibernate.HibernateInvoiceDao"
singleton="true">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- Product -->
<bean id="hibernateProductDao" class="com.postsales.domain.dao.hibernate.HibernateProductDao"
singleton="true">
<property name="sessionFactory" ref="sessionFactory" />
</bean>

<!-- Service APIs -->
<!-- Login Service -->
<bean id="loginService" parent="abstractService" singleton="true">
<property name="target">
<bean class="com.postsales.service.impl.LoginServiceImpl"
singleton="true">
<property name="hibernateuserDao" ref="hibernateuserDao" />
</bean>
</property>
</bean>
<!-- Invoice Service -->

<bean id="productService" parent="abstractService" singleton="true">
<property name="target">
<bean class="com.postsales.service.impl.ProductServiceImpl">
<property name="hibernateProductDao" ref="hibernateProductDao" />
</bean>
</property>
</bean>

<bean id="invoiceService" parent="abstractService" singleton="true">
<property name="target">
<bean class="com.postsales.service.impl.InvoiceServiceImpl">
<property name="hibernateInvoiceDao" ref="hibernateInvoiceDao" />
</bean>
</property>
</bean>
</beans>



postsales-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename">
<value>messages</value>
</property>
</bean>

<!-- you can have more than one handler defined -->

<bean id="urlMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="urlMap">
<map>
<entry key="/login.do">
<ref bean="loginController" />
</entry>
<entry key="/header.do">
<ref bean="headerController" />
</entry>
<entry key="/createInvoice.do">
<ref bean="createInvoiceController" />
</entry>
<entry key="/logout.do">
<ref bean="logoutController" />
</entry>
<entry key="/suggestPage.do">
<ref bean="pageController" />
</entry>

</map>
</property>
</bean>

<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass">
<value>org.springframework.web.servlet.view.JstlView</value>
</property>
<property name="prefix">
<value>/WEB-INF/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>

<!-- Validator Bean classes -->
<bean id="loginValidator" class="com.postsales.web.validators.LoginValidator">
</bean>

<!-- Controllers -->
<bean id="pageController" class="com.postsales.web.controller.PageController"
singleton="true" init-method="loadProducts">
<property name="productService" ref="productService"></property>
</bean>
<bean id="loginController" class="com.postsales.web.controller.LoginController"
singleton="true">
<property name="loginService" ref="loginService" />
<property name="validator" ref="loginValidator" />
<property name="commandName">
<value>loginCommand</value>
</property>
<property name="commandClass">
<value>com.postsales.web.commands.LoginCommand</value>
</property>
<property name="formView">
<value>login</value>
</property>

<property name="invoiceView">
<value>createInvoice.do</value>
</property>

</bean>
<bean id="createInvoiceController"
class="com.postsales.web.controller.secured.CreateInvoiceController"
singleton="true">
<property name="invoiceService" ref="invoiceService" />
<property name="commandName">
<value>createInvoiceCommand</value>
</property>
<property name="commandClass">
<value>com.postsales.web.commands.CreateInvoiceCommand</value>
</property>
<property name="invoiceView">
<value>createInvoice</value>
</property>

</bean>
<bean id="logoutController" class="com.postsales.web.controller.secured.LogoutController"
singleton="true">
<property name="loginService" ref="loginService" />
<property name="loginAction" value="login.do" />
</bean>
<bean id="headerController" class="com.postsales.web.controller.HeaderController"
singleton="true">
</bean>
</beans>


accountmanagement-service.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE beans PUBLIC "-SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" singleton="true">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/bankingmanagement"/>
<property name="username" value="root"/>
<property name="password" value="admin"/>
</bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" singleton="true">
<property name="dataSource" ref="dataSource"/>
<property name="mappingResources">
<list>
<value>conf/user.hbm.xml</value>
<value>conf/account.hbm.xml</value>
<value>conf/transaction.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
</value>
</property>
</bean>

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"
singleton="true">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>

<!-- Dao Implementation -->
<bean id="userDao" class="com.softnet.domain.dao.hibernate.HibernateUserDao" singleton="true">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="accountDao" class="com.softnet.domain.dao.hibernate.HibernateAccountDao" singleton="true">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="transactionDao" class="com.softnet.domain.dao.hibernate.HibernateTransactionDao" singleton="true">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>

<!-- Dao Factory -->
<bean id="daoFactory" class="com.softnet.domain.dao.DaoFactory" singleton="true">
<property name="userDao" ref="userDao"/>
<property name="accountDao" ref="accountDao"/>
<property name="transactionDao" ref="transactionDao"/>
</bean>

<!-- Services -->
<bean id="abstractService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
abstract="true">
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributes">
<props>
<prop key="insert">PROPAGATION_REQUIRED</prop>
<prop key="update">PROPAGATION_REQUIRED</prop>
<prop key="delete">PROPAGATION_REQUIRED</prop>
<prop key="withdraw">PROPAGATION_REQUIRED</prop>
<prop key="charge">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>

<bean id="userService" parent="abstractService" singleton="true">
<property name="target">
<bean class="com.softnet.service.impl.UserServiceImpl">
<property name="daoFactory" ref="daoFactory"/>
</bean>
</property>
</bean>
<bean id="accountService" parent="abstractService" singleton="true">
<property name="target">
<bean class="com.softnet.service.impl.AccountServiceImpl">
<property name="daoFactory" ref="daoFactory"/>
</bean>
</property>
</bean>

</beans>


accountmanagement-servlet.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE beans PUBLIC "-SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename">
<value>messages</value>
</property>
</bean>

<bean id="simpleUrlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"
singleton="true">
<property name="mappings">
<props>
<prop key="/login.do">loginController</prop>
<prop key="/accountDetail.do">accountDetailController</prop>
<prop key="/accountOperation.do">accountOperationController</prop>
<prop key="/logout.do">logoutController</prop>
</props>
</property>
</bean>

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"
singleton="true">
<property name="viewClass">
<value>org.springframework.web.servlet.view.JstlView</value>
</property>
<property name="prefix">
<value>/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>

<!-- Validators -->
<bean id="loginValidator" class="com.softnet.web.validators.LoginValidator"/>
<bean id="accountOperationValidator" class="com.softnet.web.validators.AccountOperationValidator"/>

<!-- Controllers -->
<bean id="loginController" class="com.softnet.web.controller.LoginController" singleton="true">
<property name="userService" ref="userService"/>
<property name="validator" ref="loginValidator"/>
<property name="commandName">
<value>loginCommand</value>
</property>
<property name="commandClass">
<value>com.softnet.web.commands.LoginCommand</value>
</property>
<property name="formView">
<value>login</value>
</property>
<property name="successView">
<value>accountDetail.do</value>
</property>
</bean>

<bean id="accountDetailController" class="com.softnet.web.controller.secured.AccountDetailController" singleton="true">
<property name="accountService" ref="accountService"/>
<property name="loginAction" value="login.do"/>
<property name="viewName" value="accountDetail"/>
</bean>

<bean id="accountOperationController" class="com.softnet.web.controller.secured.AccountOperationController"
singleton="true">
<property name="accountService" ref="accountService"/>
<property name="validator" ref="accountOperationValidator"/>
<property name="commandName">
<value>accountOperationCommand</value>
</property>
<property name="commandClass">
<value>com.softnet.web.commands.AccountOperationCommand</value>
</property>
<property name="formView">
<value>accountOperations</value>
</property>
<property name="successView">
<value>accountOperations</value>
</property>
</bean>

<bean id="logoutController" class="com.softnet.web.controller.secured.LogoutController" singleton="true">
<property name="userService" ref="userService"/>
<property name="loginAction" value="login.do"/>
</bean>


</beans>


The latest I found that the following link was handy

http://www.java2s.com/Code/Java/Hibernate/OneToManyMappingList.htm

Accourdingly I have changed my invoice.hbm.xml
<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.postsales.domain.model">
<class name="Invoice" table="invoice">
<id name="invoiceNumber" column="InvoiceNumber" />
<property name="invoiceDate" column="InvoiceDate" not-null="true" />
<property name="invoiceTotal" column="InvoiceTotal" not-null="true" />
<property name="customerName" column="CustName" not-null="true" />
<list name="sales" cascade="all">
<key column="invoiceNumber"/>
<index column="salesNumber"/>
<one-to-many class="Sales"/>
</list>
</class>
<class name="Sales" table="salesdetails">
<id name="salesNumber" column="Sales_Number" />
<property name="prodCode" column="Prod_Code" not-null="true" />
<property name="salesDate" column="Sales_Date" not-null="true" />
<property name="storeID" column="From_Store" not-null="true" />
<property name="associatedInvoice" column="InvoiceNumber"
not-null="true" />
<property name="empID" column="Emp_ID" not-null="true" />
</class>
</hibernate-mapping>


Thank you,
Kavitha.

David Newton
Author
Rancher

Joined: Sep 29, 2008
Posts: 12617

Please UseCodeTags. Unformatted code/config/etc. is difficult to read. You can edit your post to include them using the button or re-post the question with proper formatting.
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17260
    
    6

OK, first

<bean id="abstractService"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
abstract="true">
<property name="transactionManager" ref="transactionManager" />
<property name="transactionAttributes">
<props>
<prop key="insert">PROPAGATION_REQUIRED</prop>
<prop key="update">PROPAGATION_REQUIRED</prop>
<prop key="delete">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED</prop>

</props>
</property>
</bean>

I have no idea why you need that.

Also where are you declaring which methods are transactional.

It looks like you don't want or like to use annotations. At your service layer is where you will declare your methods to be transactional. That way any call from the service layer to DAOs will all be within transactions, and in the use case you described you will have one transaction started at the service layer and propagated down to all the DAO calls.

To define which service layer methods or transactional can be done either by putting @Transactional on your Service class level (All public methods in that interface are then transactional) or right above each Service method you want Transactional. The other way to define it is through xml, and you can find that information on the Spring framework website documentation.

Hope that helps

Mark
Kavita Shivani
Ranch Hand

Joined: Aug 14, 2009
Posts: 45
Hi Mark,
Thank you for your response. Not that I dont like, but I guess I dont know annotations. In the last 4 years, I had never touched any java code, I had worked on java for 2 years before that. Lately I was working on SAP technology. This year I moved to New Zealand, and could not find jobs on Sap so freelancing on java project. I did work on java before sap, so using that knowledge and trying to figure out from the internet. Problem is I am taking more time than regular developer to finish this project, and I am afraid that the project might go off my hands if I delay further, so I guess I am kind of mixing spring framework for things I can easily follow, for things that are taking time in figuring out I just skip that part and use the traditional way of doing it. For example, in my createInvoice jsp, if I am binding the command object to the page elements, I am getting one exception saying "Neither Errors instance nor plain target object for bean name 'invoice' available as request attribute" but its fine incase of Login page, I wasted like half a day, I cant waste any more time so I just removed the spring bind and used request parameters directly. So thats about it. I will look for annotations and if its less time to learn it then I might as well use it if that makes my transaction processing life easy. thing is upgrading myself and finishing the project at the same time is being quiet hectic.

Thank you for your advice on my question. I shall post any quries that I have in future.

Kavitha.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Spring-Hibernate transaction management