Mod4j: Modeling for Java using Domain Specific Languages

Spring overriding-mechanism doesn't work when overriding the tra-transactionmanager with another transactionmanager in the /service/applicationContext.xml

Details

  • Type: Bug Bug
  • Status: Resolved Resolved
  • Priority: Major Major
  • Resolution: Fixed
  • Affects Version/s: 1.0.1
  • Fix Version/s: 1.1.0
  • Component/s: DSL for Services
  • Labels:
    None
  • Environment:
    Tomcat 5.5, Oracle10i
  • Number of attachments :
    0

Description

Since tomcat is not provided with a JTA transactionmanager, overriding the <tx:jta-transaction-manager/> declaration of the applicationContextBase.xml in the applicationContext.xml is wanted. But this does not work.

Only by replacing the <tx:jta-transaction-manager/> declaration in the applicationBaseContext.xml by a specific transactionManager declarantion this can be fixed. For example:

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

<!--
<tx:jta-transaction-manager/>
-->

But of course modifying the applicationContextBase.xml does not solve anything, because it will be overwritten by each new code generation activity.

Is this a problem with the Spring overriding mechanism in general, or only for the jta-trxmgr?

Issue Links

Activity

Hide
Eric Jan Malotaux added a comment -

From the Javadoc of BeanFactory (Spring 2.5):

"In contrast to the methods in ListableBeanFactory, all of the operations in this interface will also check parent factories if this is a HierarchicalBeanFactory. If a bean is not found in this factory instance, the immediate parent factory will be asked. Beans in this factory instance are supposed to override beans of the same name in any parent factory. "

The problem with the example in this issue is that the "transactionManager" bean is overridden in a child bean factory (applicationBean.xml) of the bean factory where it is needed (applicationContextBase.txt) by the transactional advice for the services. This at least explains why overriding the transactionManager in the extension point does not work.

A possible work-around is to define all beans that use the overridden "transactionManager" as a child of the versions in the parent context and re-initialize their "transaction-manager" properties.

I will try to find better solutions.

Show
Eric Jan Malotaux added a comment - From the Javadoc of BeanFactory (Spring 2.5): "In contrast to the methods in ListableBeanFactory, all of the operations in this interface will also check parent factories if this is a HierarchicalBeanFactory. If a bean is not found in this factory instance, the immediate parent factory will be asked. Beans in this factory instance are supposed to override beans of the same name in any parent factory. " The problem with the example in this issue is that the "transactionManager" bean is overridden in a child bean factory (applicationBean.xml) of the bean factory where it is needed (applicationContextBase.txt) by the transactional advice for the services. This at least explains why overriding the transactionManager in the extension point does not work. A possible work-around is to define all beans that use the overridden "transactionManager" as a child of the versions in the parent context and re-initialize their "transaction-manager" properties. I will try to find better solutions.
Hide
Eric Jan Malotaux added a comment -

The generation gap pattern for Spring configurations is not very useful and therefore we will abandon that. Instead we will implement the following changes:

1) Generated configuration will go into "generated-resources/*//applicationContext.xml" instead of into ".../applicationContextBase.xml.
2) beanRefContext.xml will still be generated into "generated-resources/*//beanRefContext.xml" and will build just one context base on applicationContext.xml.
3) datasource, transactionManager and sessionFactory will be generated into separate XML files in data and service modules and referenced in the beanRefContext's. This makes it easier to re-use the other XML configuration files in alternative setups that use other configurations for datasource, transactionManager and/or sessionFactory.
4) The bean-references to datasource and transactionManager will use <ref bean="..."> instead of "<ref local="..."/>. This makes it possible to refer to bean definitions in other files.
5) The datasource, transactionManager and sessionFactory XML configuration files will initially be generated in "src/main/resources" as a convenience to the developer. After that they are his responsibility. This makes it easy to change these configurations.

I hope this solution strikes a good balance between simplicity and variability. The setup generated out-of-the-box is runnable right-away in a JEE-server that supports JTA transaction management. For unittesting out of container it is sufficient to create a context out of the data/applicationContext.xml and an alternative datasourceContext.xml. Or else use SimpleNamingContextBuilder to create a stand-alone JNDI provider and define the datasource etc. there. You can use the generated beanRefContext's or roll your own in your web application for instance, re-using the generated XML configuration files in the other modules.

Show
Eric Jan Malotaux added a comment - The generation gap pattern for Spring configurations is not very useful and therefore we will abandon that. Instead we will implement the following changes: 1) Generated configuration will go into "generated-resources/*//applicationContext.xml" instead of into ".../applicationContextBase.xml. 2) beanRefContext.xml will still be generated into "generated-resources/*//beanRefContext.xml" and will build just one context base on applicationContext.xml. 3) datasource, transactionManager and sessionFactory will be generated into separate XML files in data and service modules and referenced in the beanRefContext's. This makes it easier to re-use the other XML configuration files in alternative setups that use other configurations for datasource, transactionManager and/or sessionFactory. 4) The bean-references to datasource and transactionManager will use <ref bean="..."> instead of "<ref local="..."/>. This makes it possible to refer to bean definitions in other files. 5) The datasource, transactionManager and sessionFactory XML configuration files will initially be generated in "src/main/resources" as a convenience to the developer. After that they are his responsibility. This makes it easy to change these configurations. I hope this solution strikes a good balance between simplicity and variability. The setup generated out-of-the-box is runnable right-away in a JEE-server that supports JTA transaction management. For unittesting out of container it is sufficient to create a context out of the data/applicationContext.xml and an alternative datasourceContext.xml. Or else use SimpleNamingContextBuilder to create a stand-alone JNDI provider and define the datasource etc. there. You can use the generated beanRefContext's or roll your own in your web application for instance, re-using the generated XML configuration files in the other modules.
Hide
Johan Vogelzang added a comment -
  • Please describe the altered Spring mechanism in the Mod4j Application Architecture doc
  • Add the needed steps for users to upgrade from Mod4j 1.0 to Mod4j 1.1 in the Uprade notes doc.
Show
Johan Vogelzang added a comment -
  • Please describe the altered Spring mechanism in the Mod4j Application Architecture doc
  • Add the needed steps for users to upgrade from Mod4j 1.0 to Mod4j 1.1 in the Uprade notes doc.

People

Vote (0)
Watch (0)

Dates

  • Created:
    Updated:
    Resolved: