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
>> <[email protected]>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 <[email protected]>
>>>> 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: [email protected]
>>>>> For additional commands, e-mail: [email protected]
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>
>>
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
>
>
>
--
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: [email protected]
For additional commands, e-mail: [email protected]