Jeroen,

This setup is so that you can initiate and control the properties of the
transaction from the controller, if that is a pattern you require?

Do you do this for all your calls to the service layer from controllers, and
how is it better/different from a calling a service method annotated with
@Transactional(propagation=Propagation.REQUIRED) normally from the
controller?   Is it just so you can control the propagation characteristics?  

It seems like an interesting pattern, I am just wondering how it is used. 


Jeroen De Ridder wrote:
> 
> I'll agree that a service layer alone won't cut it, simply because of 
> the way JPA/Hibernate works. Updating an instance for example is just 
> something that doesn't belong in a service. I'm by no means an expert of 
> best practices in JPA/Hibernate and Spring, but I've found a combination 
> of services and anonymous runner interface instances to work quite well.
> 
> Basically, the idea is that you create a bunch of services to do routine 
> stuff to improve code clarity and avoid code duplication in your 
> actions. You'd mark these services with propagation=REQUIRED, so that 
> they can run by themselves if needed as well as run along with any 
> existing transactions. For logic that needs more than a single call to a 
> service, I then do something like this:
> 
> txr.execute(new TransactionalExecution(){
>     public void execute() {
>                    
>         Foo foo = fooService.getFoo(id);
>         if(foo != null) throw new FooException("No such foo exists!");
>        
>         foo.setName(name);
>        
>     }
> });
> 
> TransactionalExecution is just an interface with a single method 
> execute() that exists just so we can create anonymous instances of it to 
> pass to txr, which would be an instance of TransactionalExecutionRunner:
> 
> public class JpaSpringTransactionalExecutionRunner implements 
> TransactionalExecutionRunner {
>    
>     @Transactional(propagation=Propagation.REQUIRED)
>     public void execute(TransactionalExecution t) {
>         t.execute();
>     }
>    
>     @Transactional(propagation=Propagation.REQUIRES_NEW)
>     public void executeRequiresNew(TransactionalExecution t) {
>         t.execute();
>     }
>    
>     @Transactional(propagation=Propagation.MANDATORY)
>     public void executeMandatory(TransactionalExecution t) {
>         t.execute();
>     }
>    
> }
> 
> (I'm sure you can figure out what the TransactionalExecutionRunner 
> interface says). You'd then declare the transactionalExecutionRunner 
> bean in your Spring context and have it injected into every action 
> created by the Spring object factory through autowiring for example, and 
> you're good to go. The cool thing about this is that your controller 
> code stays very clear and to the point with minimal persistence bloat, 
> and that any call to a service method from within a 
> TransactionalExecution will automatically run within the ongoing 
> transaction.
> 
> As for your configuration, other than your applicationContext.xml file 
> you shouldn't have to do anything other than include the spring plugin 
> jar in your classpath. The jar comes with a struts-default.xml file that 
> sets Spring as the default object factory. Of course, it can never hurt 
> to explicitly set the objectFactory; I'm using 
> struts.objectFactory=org.apache.struts2.spring.StrutsSpringObjectFactory, 
> but struts.objectFactory=spring should work equally well.
> 
> -- Jeroen
> 
>> Hi Jeroen,
>>
>> The problem is that I am not a big fan of services layer. Sometimes it
>> looks
>> very anemic to me. But I totally agree with you when you say the action
>> should not know about persistence problems, and that's why I want to do
>> it
>> via AOP.
>>
>> I had the same thought about the problem: the Spring proxy does not work
>> properly with all the magic Struts2 and Reflection do!
>>
>> I tried to open a bug in the Struts2 JIRA, but they closed it and said
>> that
>> it works. I think it should be some kind of spring or struts
>> configuration I
>> am not doing right.
>>
>> Thanks in advance,
>> Mauricio
>>
>> On Thu, Apr 30, 2009 at 11:22 PM, Jeroen De Ridder
>> <voetsjo...@gmail.com>wrote:
>>
>>   
>>> You really shouldn't be making your Struts 2 actions @Transactional.
>>> Doing
>>> that causes Spring to create a proxy so it can put some extra
>>> transaction-handling logic between the method call and the actual
>>> method.
>>> The thing is, Struts 2 and OGNL rely heavily on reflection on the action
>>> classes which simply does not work at all with the proxies created by
>>> Spring.
>>>
>>> Regardless, making your actions @Transactional means mixing persistence
>>> concerns with controller logic in the same class. You should consider
>>> keeping the two separated. For example, the service approach is a good
>>> start:
>>> http://struts.apache.org/2.0.14/docs/struts-2-spring-2-jpa-ajax.html.
>>>
>>>
>>>  Yes, I am. Everything works fine when I don't try to use Spring
>>>     
>>>> transactional AOP!
>>>>
>>>> Mauricio
>>>>
>>>> On Thu, Apr 30, 2009 at 9:43 PM, Dave Newton <newton.d...@yahoo.com>
>>>> wrote:
>>>>
>>>>
>>>>
>>>>       
>>>>> Mauricio Aniche wrote:
>>>>>
>>>>>
>>>>>
>>>>>         
>>>>>> I am using Struts2+Spring+JPA/Hibernate. When I use the
>>>>>> @Transactional
>>>>>> to
>>>>>> mark an execute() method in a Struts2 Action, the action stops
>>>>>> working
>>>>>> properly (i.e. the attributes in the action are not automatically
>>>>>> setted).
>>>>>> It does not work with Spring AOP transactions as well.
>>>>>>
>>>>>> In my struts.config I setted the following constant:
>>>>>> ----
>>>>>> <constant name="struts.objectFactory" value="spring" />
>>>>>>
>>>>>>
>>>>>>
>>>>>>           
>>>>> You're using the Spring plugin, correct?
>>>>>
>>>>> Dave
>>>>>
>>>>>
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe, e-mail: user-unsubscr...@struts.apache.org
>>>>> For additional commands, e-mail: user-h...@struts.apache.org
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>         
>>>>
>>>>       
>>>     
>>
>>   
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscr...@struts.apache.org
> For additional commands, e-mail: user-h...@struts.apache.org
> 
> 
> 

-- 
View this message in context: 
http://www.nabble.com/%40Transactional-Spring-Annotation-in-a-Struts2-Action-does-not-work-tp23326798p23348253.html
Sent from the Struts - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscr...@struts.apache.org
For additional commands, e-mail: user-h...@struts.apache.org

Reply via email to