-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 
Author Message
 Post subject: Declarative transactions in Spring
PostPosted: Wed Jun 23, 2004 3:50 pm 
Beginner
Beginner

Joined: Tue Jun 22, 2004 7:50 am
Posts: 25
I've got most of my persistence working: queries work and so do updates: except the updates don't "stick" which makes me think that I haven't got transactions working.

I have a Product JavaBean and a ProductManager JavaBean which has an associate ProductManagerDao interface and a concrete ProductManagerDaoHibernate.

Code:
    <bean id="prodManDao" class="db.ProductManagerDaoHibernate">
        <property name="sessionFactory"><ref local="sessionFactory"/></property>
    </bean>

    <bean id="prodMan" class="bus.ProductManager">
        <property name="productManagerDao">
            <ref bean="prodManDao"/>
        </property>
    </bean>

    <bean id="myTransactionManager"
            class="org.springframework.orm.hibernate.HibernateTransactionManager">
        <property name="sessionFactory">
            <ref bean="sessionFactory"/>
        </property>
    </bean>

    <bean id="myProductService"
            class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">

        <property name="transactionManager">
            <ref bean="myTransactionManager"/>
        </property>

        <property name="target">
            <ref bean="prodManDao"/>
        </property>

        <property name="transactionAttributes">
            <props>
                <prop key="increasePrice*">PROPAGATION_REQUIRED</prop>
                <prop key="*">PROPAGATION_SUPPORTS</prop>
            </props>
        </property>


and

Code:
package db;

import bus.Product;
import java.util.List;
import java.util.ListIterator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.orm.hibernate.support.HibernateDaoSupport;
import org.springframework.orm.hibernate.SessionFactoryUtils;

import net.sf.hibernate.*;

public class ProductManagerDaoHibernate extends HibernateDaoSupport implements ProductManagerDao
{
    private final Log logger = LogFactory.getLog(getClass());
   
    public List getProductList()
    {
        logger.info("Getting products!");

        List products = null;
        Session session = null;
        try
        {
            session = SessionFactoryUtils.getSession(getSessionFactory(), true);

            // A Hibernate criteria query
            Criteria criteria = session.createCriteria(Product.class);
            //criteria.addOrder(Order.asc("title"));
            products = criteria.list();
        }
        catch (HibernateException he)
        {
            logger.warn(he);
        }
        finally
        {
            SessionFactoryUtils.closeSessionIfNecessary(session, getSessionFactory());
        }
        return products;
    }
   
    public void increasePrice(int pct)
    {
        logger.info("Increasing price by " + pct + "%");
        Session session = null;
        try
        {
            session = SessionFactoryUtils.getSession(getSessionFactory(), true);

        // A Hibernate criteria query
            Criteria criteria = session.createCriteria(Product.class);
        //criteria.addOrder(Order.asc("title"));
            List products = criteria.list();
            ListIterator iter = products.listIterator();
            while (iter.hasNext())
            {
                Product product = (Product)iter.next();
                product.setPrice(new Double(product.getPrice().doubleValue() * (100 + pct) / 100));
            }
        }
        catch (HibernateException he)
        {
            logger.warn(he);
        }
        finally
        {
            SessionFactoryUtils.closeSessionIfNecessary(session, getSessionFactory());
        }
    }
}


Any suggestions as to what I'm doing wrong ?


Top
 Profile  
 
 Post subject: Thinking about this further...
PostPosted: Wed Jun 23, 2004 4:21 pm 
Beginner
Beginner

Joined: Tue Jun 22, 2004 7:50 am
Posts: 25
The problem seems to be I don't actually use this bean

[code]


Top
 Profile  
 
 Post subject: Solved.
PostPosted: Thu Jun 24, 2004 4:24 am 
Beginner
Beginner

Joined: Tue Jun 22, 2004 7:50 am
Posts: 25
OK solved it. Basically I stick the transaction proxy bean between my code and the actual bean doing the work by giving it the bean id of the bean it's proxying.

So if my DAO bean that I want to make transactional is ProductManagerDaoHib with a bean id of myProductManagerDAO then I wrap it in the transactioncal bean. Basically I change the name of the wrapped bean (to say myProductManagerDAOTarget give that to the transactional wrapper bean and give that the bean id of the wrapped bean eg ProductManagerDAO).

What was initially tripping me up was that I was getting out of memory errors from Tomcat 5 (which seems to be a bit unstable) and thought that was my problem when it wasn't. A quite re-boot and everything works fine.

Edward


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 25, 2004 3:11 am 
Senior
Senior

Joined: Wed Aug 27, 2003 6:04 am
Posts: 161
Location: Linz, Austria
Note that you shouldn't log HibernateExceptions as warnings: Better convert them to Spring's unchecked DataAccessException hierarchy, for example via

Code:
throw SessionFactoryUtils.convertHibernateAccessExcepton(he);


If you derive from HibernateDaoSupport, you can even simplify that by access the base class' convenience methods. I've also streamlined the rest of the code a bit.

Code:
public List getProductList() {
    Session session = null;
    try {
        session = [i]getSession(true)[/i];
        Criteria criteria = session.createCriteria(Product.class);
        //criteria.addOrder(Order.asc("title"));
        return criteria.list();
    }
    catch (HibernateException he) {
        throw [i]convertHibernateAccessException(he)[/i];
    }
    finally {
        [i]closeSessionIfNecessary(session)[/i];
    }
}


Alternatively, you could implement that as HibernateCallback. This results in significantly shorter code, as the template will care for Session opening and closing and for conversion of HibernateExceptions to Spring's DataAccessException hierarchy.

Code:
public List getProductList() {
    return getHibernateTemplate().executeFind(new HibernateCallback() {
        public Object doInHibernate(Session session) throws HibernateException {
        Criteria criteria = session.createCriteria(Product.class);
        //criteria.addOrder(Order.asc("title"));
        return criteria.list();
    });
}


Even simpler than that, try to leverage HibernateTemplate's operation methods as far as possible. Those methods provide an extensive set of typical operations, with full resource and exception management. For example, to retrieve all Products:

Code:
public List getProductList() {
    return getHibernateTemplate().loadAll(Product.class);
}


For sorting by title, you could use "find" with a corresponding HQL query. HQL lends itself very nicely for one-line operation objects. Of course, if you prefer the Criteria API, you can still use that (see above).

Code:
public List getProductList() {
    return getHibernateTemplate().find("from Product order by title asc");
}


Juergen


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 25, 2004 3:47 am 
Beginner
Beginner

Joined: Tue Jun 22, 2004 7:50 am
Posts: 25
That's excellent, just what I needed, thanks very much Juergen.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.