Alupkers
Alupkers

Reputation: 223

How to create transactional proxy through factory-method?

I have a spring bean that is created through factory-method and I also need to use @Transactional facility. So, when I create it as follows:

<bean id="myBean" class="pack.age.MyBean" factory-method="create">
    <constructor-arg ref="someBean" />
</bean>

where

public class MyBean implements MyInterface{

    private final SomeBean someBean;

    public static MyInterface create(SomeBean someBean){
        MyBean retVal = new MyBean(someBean);
        //Create a thread and run it.
        //Do some other job that doesn't suit for constructor
    }

    private MyBean(SomeBean someBean){
         this.someBean = someBean;
    }
}

Now, when I try to inject the bean into anothe bean:

public class MyAnotherBean{

    private MyInterface myInterface;


    public boid setMyInterface(MyInterface myInterface){
        this.myInterface = myInterface;
    }
}

declared as

<bean id="myAnotherBean" class="pack.age.MyAnotherBean">
    <property name="myInterface" ref="myBean" />
</bean>

The actual myBean instance, not a proxy is injected. Since it's not a proxy, I can't use Spring @Transactional facility.

How can I inject a proxy when constructing an object through static factory-method?

Upvotes: 0

Views: 209

Answers (1)

vinycd
vinycd

Reputation: 97

In this case just enabling transaction annotation under the beans declaration should work:

<tx:annotation-driven transaction-manager="txManager"/>
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <!-- (this dependency is defined somewhere else) -->
    <property name="dataSource" ref="dataSource"/>
</bean>

But if not you can try enable the transaction declaratively:

<tx:advice id="txAdvice" transaction-manager="txManager">
    <!-- the transactional semantics... -->
    <tx:attributes>
        <!-- all methods starting with 'get' are read-only -->
        <tx:method name="get*" read-only="true"/>
        <!-- other methods use the default transaction settings (see below) -->
        <tx:method name="*"/>
    </tx:attributes>
</tx:advice>

<!-- ensure that the above transactional advice runs for any execution
    of an operation defined by the MyInterface interface -->
<aop:config>
    <aop:pointcut id="myBeanOperation" expression="execution(* x.y.service.MyInterface.*(..))"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="myBeanOperation"/>
</aop:config>

Upvotes: 1

Related Questions