Announcement Announcement Module
Collapse
No announcement yet.
iBatis 2.0 SqlMapClientTemplate not populated Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • iBatis 2.0 SqlMapClientTemplate not populated

    Hello,

    I am trying to getSqlMapClientTemplate within my DAOobj extending SqlMapClientDaoSupport.

    When I to the getSqlMapClientTemplate() within the DAOobj; the template is returned with unpopulated values (no datasource, no sqlmapclient).

    :roll: I thought the SqlMapClientTemplate would be populated in the DAO definition / IBATIS impl. under the covers of spring init...

    Its weird as the app starts all beans are initialized with no exceptions.

    here's a snippet:

    dataAccessContext.xml

    Code:
    <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
    		<property name="configLocation"><value>/WEB-INF/sql-map-config.xml</value></property>
    		<property name="dataSource"><ref local="dataSource"/></property>
    	</bean>
    
    	<bean id="userTypeDao" class="com.td.isportal.dao.ibatis.SqlMapUserTypeDAO">
    		<property name="sqlMapClient"><ref local="sqlMapClient"/></property>
    	</bean>
    DAOobj

    Code:
    public class SqlMapUserTypeDAO extends SqlMapClientDaoSupport implements UserTypeDAO&#123;
    	
    
    	/* &#40;non-Javadoc&#41;
    	 * @see com.td.isportal.dao.ISPortalUserTypeDAO#getUserTypeData&#40;java.lang.String&#41;
    	 */
    	public UserTypeData getUserTypeData&#40;String connectId&#41; throws DataAccessException&#123;
    		SqlMapClientTemplate template = getSqlMapClientTemplate&#40;&#41;;
    		return &#40;UserTypeData&#41; template.queryForObject&#40;"getUserTypeData", connectId&#41;;
    	&#125;
    
    &#125;

  • #2
    I'm using Spring version 1.1.4 and have no problems.
    This is the code from SqlMapClientDaoSupport and as you can see, it does what you need:

    private SqlMapClientTemplate sqlMapClientTemplate = new SqlMapClientTemplate();

    private boolean externalTemplate = false;


    /**
    * Set the JDBC DataSource to be used by this DAO.
    * Not required: The SqlMapClient might carry a shared DataSource.
    * @see #setSqlMapClient
    */
    public final void setDataSource(DataSource dataSource) {
    this.sqlMapClientTemplate.setDataSource(dataSource );
    }

    /**
    * Return the JDBC DataSource used by this DAO.
    */
    public final DataSource getDataSource() {
    return (this.sqlMapClientTemplate != null ? this.sqlMapClientTemplate.getDataSource() : null);
    }

    /**
    * Set the iBATIS Database Layer SqlMapClient to work with.
    * Either this or a "sqlMapClientTemplate" is required.
    * @see #setSqlMapClientTemplate
    */
    public final void setSqlMapClient(SqlMapClient sqlMapClient) {
    this.sqlMapClientTemplate.setSqlMapClient(sqlMapCl ient);
    }

    /**
    * Return the iBATIS Database Layer SqlMapClient that this template works with.
    */
    public final SqlMapClient getSqlMapClient() {
    return this.sqlMapClientTemplate.getSqlMapClient();
    }

    /**
    * Set the SqlMapClientTemplate for this DAO explicitly,
    * as an alternative to specifying a SqlMapClient.
    * @see #setSqlMapClient
    */
    public final void setSqlMapClientTemplate(SqlMapClientTemplate sqlMapClientTemplate) {
    if (sqlMapClientTemplate == null) {
    throw new IllegalArgumentException("Cannot set sqlMapClientTemplate to null");
    }
    this.sqlMapClientTemplate = sqlMapClientTemplate;
    this.externalTemplate = true;
    }

    /**
    * Return the SqlMapClientTemplate for this DAO,
    * pre-initialized with the SqlMapClient or set explicitly.
    */
    public final SqlMapClientTemplate getSqlMapClientTemplate() {
    return sqlMapClientTemplate;
    }

    Comment


    • #3
      I'm still having problems... what could cause an empty sqlMapClientTemplate without throwing exceptions at startup?

      Comment


      • #4
        On startup; I set a breakpoint at super.initDao() within my DAOobj.
        The SqlMapClient is populated with my maps etc. although my dataSource is null.

        At runtime when accessing the sqlMapClientTemplate through the DAOobj it is NOT the same instance as the instance viewed at super.initDao();

        My next steps are to either load the spring source and step through or use a previous version of iBatis.

        Can anyone help me?

        Thanks in Advance.

        Comment


        • #5
          May I ask how you are getting a reference to the DAO itself?

          Geoff

          Comment


          • #6
            Hi, sorry for digging out such an old topic, but... I'm getting virtually the same error.

            I'm using Spring 2.5.5 and IBatis 2.3.4, this is my Spring config:
            HTML Code:
            <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean" scope="singleton">
            	<property name="jndiName" value="jdbc/postgres"/>
            	<property name="resourceRef" value="true"/>
            </bean>
            	
            
            <bean id="sqlMapClientTemplate" class="org.springframework.orm.ibatis.SqlMapClientTemplate">
            	<property name="sqlMapClient">
            		<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
            			<property name="dataSource" ref="dataSource" />
            			<property name="configLocation" value="WEB-INF/sql-map-config.xml" />
            		</bean>
            	</property>
            </bean>
            	
            <bean id="countriesDao" class=my.dao.IBatisCountriesDao">
            	<property name="sqlMapClientTemplate" ref="sqlMapClientTemplate" />
            </bean>
            Everything gets initialised correctly, but calling my countriesDao's
            Code:
            return getSqlMapClientTemplate().queryForList("getCountries");
            throws NullPointerException. The problem is that the SqlMapClientTemplate disappears somewhere - it's definitely injected into the DAO and it's not null at that point, but somehow it becomes null when I'm trying to use it (magic?).
            I don't really know what to do now, I found something a bit similar on IBatis' JIRA (IBATIS-464), but it didn't solve my problem.

            The only solution I can think of at the moment is not to use iBatis at all.... Anyone has a better one?


            Thanks for any help,
            L.

            Comment


            • #7
              Hi lkr,

              Did you ever resolve this - I'm coming up with the same problem trying to run Spring / iBatis with JSF in Tomcat 6.0. I'm getting no errors at start-up, but sqlMapClient keeps returning null when I try to use it.

              Being new to Spring / iBatis I'm beginning to wonder just what the point is - I could have done this in half the time / frustration with good old fashioned JDBC!

              J.

              Comment


              • #8
                Hello,
                unfortunately I had no time nor willingness to fix that, I used a different approach instead. I ruled Spring out of the equation, I created a custom abstract IBatisDAO instead:

                Code:
                public abstract class AbstractIbatisDao {
                  private SqlMapClient sqlMapClient;
                  private String configFileLocation = "sql-map-config.xml";
                
                  public AbstractIbatisDao() {
                    Reader reader = null;
                
                    try {
                      reader = Resources.getResourceAsReader(configFileLocation);
                    } catch (IOException e) {
                            // catch block
                    }
                
                    this.sqlMapClient = SqlMapClientBuilder.buildSqlMapClient(reader);
                  }
                
                  public SqlMapClient getSqlMapClient() {
                    return sqlMapClient;
                  }
                }
                Now all my DAOs sublass it, and the SqlMapClient is exposed through getSqlMapClient() method.

                I also moved the dataSource definition to sql-map-config.xml file:

                HTML Code:
                <transactionManager type="JDBC">
                     <dataSource type="JNDI">
                            <property name="DataSource" value="java:/comp/env/jdbc/postgres"/>
                         </dataSource>
                </transactionManager>
                It works fine, I know it is not as flexible as if it used Spring (ie. sql-map file location is hardcoded), but I haven't experienced any shortcomings of this approach yet. The only one was that I had to create a separate sql-map-config.xml file for testing purposes (which has to be kept in sync with the 'live' file manually), but I think it's still better than using pure JDBC.

                I hope it helps a little!

                cheers,
                LK
                Last edited by lkr; Dec 3rd, 2008, 08:12 AM.

                Comment


                • #9
                  Thanks for the code, everything now works a treat. I'm going to spend a bit more time trying to get Spring working, so if I get anywhere I'll let you know.

                  cheers,
                  J.

                  Comment

                  Working...
                  X