Results 1 to 5 of 5

Thread: getBean from within a proxied bean

Hybrid View

  1. #1
    Join Date
    Sep 2004
    Location
    Argentina
    Posts
    23

    Default getBean from within a proxied bean

    Hi i'm having the following problem
    Given the following classes:
    - StudentDao -> target of TransactionProxyFactoryBean
    - SequenceDao -> idem StudentDao

    SequenceDao is used from StudentDao to obtain the next value in a sequece for autoincremental primary key value. The problem is that when i call getBean from the ApplicationContext i get a Proxy object that can't be casted to SequenceDao because a ClassCastException is thrown. Can somebody tell me what's wrong?

    When obtained with getBean from outside StudentDao, the SequenceDao proxy can be casted without exceptions being thrown
    - N!K -

  2. #2
    Join Date
    Aug 2004
    Location
    San Mateo, CA
    Posts
    1,265

    Default

    Can you please post class definitions (without the body code) and config, so it's easier to figure out what's going on and I can reproduce this scenario? I can't see any potential cause of a problem so far...
    Rod Johnson - GM, SpringSource Division, VMware
    http://www.springsource.com
    Spring From the Source

  3. #3
    Join Date
    Sep 2004
    Location
    Argentina
    Posts
    23

    Default

    Here goes the code
    applicationContext.xml
    Code:
    <beans>
        <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="locations">
                <list>
                    <value>WEB-INF/jdbc.properties</value>
                </list>
            </property>
        </bean>
    
        <bean id="citFacade" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
            <property name="transactionManager">
                <ref bean="transactionManager"/>
            </property>
            <property name="target">
                <bean class="com.sep.padron.business.facade.CITFacade">
                    <property name="entityDao">
                        <ref bean="entityDao"/>
                    </property>
                </bean>
            </property>
            <property name="transactionAttributes">
                <props>
                    <prop key="*">PROPAGATION_REQUIRED,-com.sep.padron.business.exception.SystemException</prop>
                </props>
            </property>
        </bean>
    
        <bean id="sequenceDao" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
            <property name="transactionManager">
                <ref bean="transactionManager"/>
            </property>
            <property name="target">
                <ref bean="sequenceDaoTarget"/>
            </property>
            <property name="transactionAttributes">
                <props>
                    <prop key="*">PROPAGATION_REQUIRES_NEW</prop>
                </props>
            </property>
        </bean>
    </beans>
    dataAccessContext.xml
    Code:
    <beans>
    
        <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
            <property name="jndiName">
                <value>$&#123;dataSource.jndiName&#125;</value>
            </property>
        </bean>
    
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource">
                <ref local="dataSource"/>
            </property>
        </bean>
    
        <bean id="sqlMap" class="org.springframework.orm.ibatis.SqlMapFactoryBean">
            <property name="configLocation">
                <value>/WEB-INF/sql-map-config.xml</value>
            </property>
        </bean>
    
        <bean id="entityDao" class="com.sep.padron.persistence.ibatis.SqlMapEntityDao">
            <property name="dataSource">
                <ref local="dataSource"/>
            </property>
            <property name="sqlMap">
                <ref local="sqlMap"/>
            </property>
            <property name="sequenceDaoName">
                <value>sequenceDao</value>
            </property>
        </bean>
    
        <!-- Sequence generator -->
        <bean id="sequenceDaoTarget" class="com.sep.padron.persistence.ibatis.SqlMapSequenceDao">
            <property name="dataSource">
                <ref local="dataSource"/>
            </property>
            <property name="sqlMap">
                <ref local="sqlMap"/>
            </property>
        </bean>
    </beans>
    SqlMapSequenceDao
    Code:
    public class SqlMapSequenceDao extends SqlMapDaoSupport implements SequenceDAO&#123;
        public Integer getNextValue&#40;String sequenceName&#41;&#123;
           // fetch next sequence value from 'SEQUENCE' table
        &#125;
    &#125;
    SqlMapEntityDao
    Code:
    public class SqlMapEntityDao extends SequenceDependentDao implements EntityDAO&#123;
        public String insertRow&#40;Entity entity&#41; &#123;
            entity.setEntityId&#40;
                    super.getSequenceDao&#40;&#41;.getNextValue&#40;"C_ENTIDAD.ENTIDAD_ID"&#41;.toString&#40;&#41;&#41;;
            super.getSqlMapTemplate&#40;&#41;.executeUpdate&#40;"insertEntity", entity&#41;;
    
            return entity.getEntityId&#40;&#41;;
        &#125;
    &#125;
    SequenceDependentDao
    Code:
    1 -public class SequenceDependentDao extends SqlMapDaoSupport implements ApplicationContextAware&#123;
    2 -    private String sequenceDaoName;
    3 -    private ApplicationContext applicationContext;
    4 -
    5 -    public SqlMapSequenceDao getSequenceDao&#40;&#41;&#123;
    6 -        return &#40;SqlMapSequenceDao&#41; this.applicationContext.getBean&#40;this.sequenceDaoName&#41;; 
    7 -    &#125;
    8 -
    9 -    public void setSequenceDaoName&#40;String sequenceDaoName&#41;&#123;
    10-        this.sequenceDaoName = sequenceDaoName;
    11-    &#125;
    12-
    13-    public void setApplicationContext&#40;ApplicationContext applicationContext&#41; throws BeansException&#123;
    14-        this.applicationContext = applicationContext;
    15-    &#125;
    16-&#125;
    In line 6 is where i get a ClassCastException because the object returned by getBean is an instance of Proxy

    I hope this can help you help me :P
    - N!K -

  4. #4
    Join Date
    Aug 2004
    Location
    San Mateo, CA
    Posts
    1,265

    Default

    Thanks. The problem is that you're trying to cast the proxy to SqlMapSequenceDao, which is a class. By default Spring AOP uses JDK dynamic proxies, which can only proxy interfaces. Thus your proxy is only implementing the interface SequenceDAO. The AOP framework assumes that you won't try to cast to the actual implementing class.

    You can easily do what you want to do. You simply need to force the TransactionProxyFactoryBean to use CGLIB proxying, by setting its "proxyTargetClass" property to true. You will then need to add the CGLIB Jar from the Spring distribution to your application classpath, if it's not there already (for example, if you use Hibernate as well as Spring).

    Rgds
    Rod
    Rod Johnson - GM, SpringSource Division, VMware
    http://www.springsource.com
    Spring From the Source

  5. #5
    Join Date
    Sep 2004
    Location
    Argentina
    Posts
    23

    Default

    Rod, thank you very much.
    It finally worked.
    - N!K -

Similar Threads

  1. Order of Bean definitions matters?
    By cfuser in forum Container
    Replies: 2
    Last Post: Oct 21st, 2005, 10:29 AM
  2. Spring container fails with no exception
    By naor in forum Container
    Replies: 9
    Last Post: Oct 1st, 2005, 03:39 PM
  3. EHCaching Hibernate
    By dencamel in forum Data
    Replies: 3
    Last Post: Sep 6th, 2005, 09:03 PM
  4. could not satisfy dependencies
    By springuser in forum Container
    Replies: 4
    Last Post: Apr 26th, 2005, 01:15 PM
  5. Replies: 1
    Last Post: Apr 25th, 2005, 07:37 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •