0
votes

I have a dao package where all my DaoClasses implements amongst others the following methode:

public class XDaoImpl implements XDao {

    private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    public SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    @Override
    public void saveOrUpdate(MyObject o) {
            //Transaction trans = getSessionFactory().getCurrentSession().beginTransaction();
            getSessionFactory().getCurrentSession().saveOrUpdate(o); 
            //trans.commit();
        }
}

If I run my application it needs a lot time to store my objects to the database. I belief it happens because I create a new Transaction for each object. So I tried to use Spring Framework’s xml based declarative transaction implementation. But till now it does not work for me:

<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"
     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.xsd
                           http://www.springframework.org/schema/aop
                           http://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location">
            <value>/resources/spring/config/database.properties</value>
        </property>
    </bean>


    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <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="hibernate3SessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

        <property name="dataSource" ref="dataSource" />

        <property name="mappingResources">
            <list>
                <value>/resources/spring/config/A.hbm.xml</value>
                <value>/resources/spring/config/B.hbm.xml</value>
                <value>/resources/spring/config/C.hbm.xml</value>
                <value>/resources/spring/config/D.hbm.xml</value>
            </list>
        </property>

        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
                <prop key="hibernate.current_session_context_class">thread</prop>
                <prop key="hibernate.hbm2ddl.auto">create</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>

    </bean>

    <bean id="dBo" class="com.model.bo.DBoImpl">
        <property name="dDao" ref="dDao" />
        <property name="bDao" ref="bDao" />
    </bean>

    <bean id="dDao" class="com.model.dao.dDaoImpl">
        <property name="sessionFactory" ref="hibernate3SessionFactory" />
    </bean>

    <bean id="aBo" class="com.model.bo.aBoImpl">
        <property name="aDao" ref="aDao" />
        <property name="bDao" ref="bDao" />
        <property name="cDao" ref="cDao" />
    </bean>

    <bean id="bDao" class="com.model.dao.bDaoImpl">
        <property name="sessionFactory" ref="hibernate3SessionFactory" />
    </bean>

    <bean id="cDao" class="com.model.dao.cDaoImpl">
        <property name="sessionFactory" ref="hibernate3SessionFactory" />
    </bean>
    <bean id="aDao" class="com.model.dao.aDaoImpl">
        <property name="sessionFactory" ref="hibernate3SessionFactory" />
    </bean>

     <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="hibernate3SessionFactory" />
    </bean>
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="get*" read-only="true" />
            <tx:method name="*" propagation="REQUIRED" />
        </tx:attributes>
    </tx:advice>
    <aop:config>
        <aop:pointcut id="boMethods" expression="execution(* com.model.bo.*.*(..))" />

        <aop:advisor advice-ref="txAdvice" pointcut-ref="boMethods" />
    </aop:config> 
    </beans>

The error that is thrown:

class org.springframework.beans.factory.BeanCreationException Error creating bean with name 'dataSource' defined in class path resource [resources/spring/config/BeanLocations.xml]: BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0': Cannot resolve reference to bean 'boMethods' while setting bean property 'pointcut'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'boMethods': Instantiation of bean failed; nested exception is java.lang.NoClassDefFoundError: org/aspectj/weaver/BCException

public class DBoImpl implements DBo {

    private DDao dDao;
    private BDao bDao;


    public DDao getDDao() {
        return dDao;
    }

    public void setDDao(DDao dDao) {
        this.dDao = dDao;
    }

    public BDao getbDao() {
        return bDao;
    }

    public void setbDao(BDao bDao) {
        this.bDao = bDao;
    }

public D add(D r) {
        dDao.saveOrUpdate(r);
        return r;
    }

}
2

2 Answers

0
votes

It looks like you don't have the AOP jar files in your class path.

See: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html

Look for the section "10.2.1 Enabling @AspectJ Support"

0
votes

Using AOP for transactional behavior is fine. I'd suggest having a look at annotation based configuration (Note the <tx:annotation-driven transaction-manager="transactionManager" />), which might be a little bit more straightforward.

Furthermore I would be careful about using this configuration. A transaction is meant to encapsulate an atomic unit of work. Having a method like saveOrUpdate(EntityType entity) I'd think your atomic unit of work was saving one entity, not saving n entities. The longer a transaction runs, the greater gets the probability of running into deadlocks.

I'd suggest creating a Method like public void saveOrUpdateInBatch(MyObject... objects). The name implies you are dealing with an atomic operation which handles a number of elements. Also you might want to optimize this method for batch inserts.