Announcement Announcement Module
Collapse
No announcement yet.
Spring + iBatis - out of memory!! Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Teseo
    started a topic Spring + iBatis - out of memory!!

    Spring + iBatis - out of memory!!

    Hi, I´m having a problem with Spring + iBatis. The program loops forever and ends up with an out of memory error. here´s the code.


    applicationContext-jdbc.xml
    Code:
    <beans>
    	<!-- ========================= RESOURCE DEFINITIONS ========================= -->
    	<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    		<property name="location"><value>/bin/jdbc.properties</value></property>
    	</bean>
    	<!-- DataSource local que trajaba en cualquier entorno -->
    	<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    		<property name="driverClassName"><value>$&#123;jdbc.driverClassName&#125;</value></property>
    		<property name="url"><value>$&#123;jdbc.url&#125;</value></property>
    		<property name="username"><value>$&#123;jdbc.username&#125;</value></property>
    		<property name="password"><value>$&#123;jdbc.password&#125;</value></property>
    	</bean>
    	<!-- Mapping para la configuracion de iBatis -->
    	<bean id="sqlMap" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
    		<property name="configLocation"><value>/iBatis/sql-map-config.xml</value></property>
    	</bean>
    	<bean id="productDao" class="com.company.sample.persistence.jdbc.jdbc.ProductDaoImpl">
    		<property name="dataSource"><ref local="dataSource"/></property>
    		<property name="sqlMap"><ref local="sqlMap"/></property>
    	</bean>
    </beans>

    Product.xml
    Code:
    <sqlMap namespace="Products">
    
    	<cacheModel id="products-cache" type="MEMORY">
    		<flushInterval hours="24"/>
    		<flushOnExecute statement="insertProduct"/>
    		<flushOnExecute statement="updateProduct"/>
    		<flushOnExecute statement="deleteProduct"/>
    		<property name="reference-type" value="WEAK" />
    	</cacheModel>
    	
    	<typeAlias alias="product" type="com.company.sample.persistence.jdbc.dto.Product" />
    	<typeAlias alias="productPk" type="com.company.sample.persistence.jdbc.dto.ProductPk" />
    
    	<resultMap class="product" id="product-result" >
    		<result property="id" column="ID" />
    		<result property="description" column="DESCRIPTION" />
    	</resultMap>
    
    	<select id="getProduct" resultClass="product" parameterClass="productPk" resultMap="product-result" >
    		<!&#91;CDATA&#91;
    			select * from Referencia.PRODUCTS 
    			where ID = #id#
    		&#93;&#93;>
    	</select>
    
    	<update id="updateProduct" parameterClass="product" >
    		<!&#91;CDATA&#91;
    			update Referencia.PRODUCTS
    			set DESCRIPTION = #description#
    			where ID = #id#
    		&#93;&#93;>
    	</update>
    
    	<insert id="insertProduct" parameterClass="product" >
    		<!&#91;CDATA&#91;
    			insert into Referencia.PRODUCTS&#40;ID, DESCRIPTION&#41;
    			values&#40;#id#, #description#&#41;
    		&#93;&#93;>
    	</insert>	
    
    	<delete id="deleteProduct" parameterClass="productPk" >
    		<!&#91;CDATA&#91;
    			delete from Referencia.PRODUCTS
    			where ID = #id#
    		&#93;&#93;>
    	</delete>
    
    </sqlMap>
    Implementation of the ProductDao (ProductDao extendes SqlMapDao, SqlMapDao extends SqlMapDaoSupport)

    Code:
    public class ProductDaoImpl extends ProductDao &#123; 
       	protected static final Logger logger = Logger.getLogger&#40; ProductDaoImpl.class &#41;;
    			
        
        /* Inserts a new row in the PRODUCTS table.
         * @see com.company.framework.dao.core.Dao#insert&#40;java.lang.Object&#41;
         */
        public Object insert&#40;Object dto&#41; throws companyDataAccessException &#123;
        	Product product = &#40;Product&#41; dto;
    		if &#40;logger.isDebugEnabled&#40;&#41;&#41; &#123;
    			logger.debug&#40; "Executing " + SQL_INSERT + " with DTO&#58; " + product&#41;;
    		&#125;
    		this.getSqlMapTemplate&#40;&#41;.executeUpdate&#40;"insertProduct", new Object&#91;&#93; &#123;product.getId&#40;&#41;,product.getDescription&#40;&#41;&#125; &#41;;
    		return product.createPk&#40;&#41;;
        &#125;
        .....
        &#125;
    Test Code

    Code:
    ProductDao dao = ProductDaoFactory.create&#40;&#41;;
    Product product = new Product&#40;&#41;;
    product.setId&#40;new Integer&#40;1&#41;&#41;;
    product.setDescription&#40;"Producto el orto"&#41;;
    dao.insert&#40;product&#41;;
    System.out.println&#40;dao.findByPrimaryKey&#40;product.createPk&#40;&#41;&#41;&#41;;
    What´s wrong with these. I'm debugging the application but it seems to loop while initializing the beans.

  • Rod Johnson
    replied
    I still need help with the test cases. How should I create and drop the tables??..
    Look at the org.springframework.test package, shipped in spring-mock.jar. I've updated the PetClinic tests to use it (just post 1.1.4, unfortunately), and added a chapter in the Reference Manual (which also may not be published yet, but should be available soon).

    This is designed to run each test in its own transaction, rolling back by default. I've found it a very convenient technique for testing involving a database, and it's produced a big productivity benefit in several projects.

    Leave a comment:


  • Teseo
    replied
    I've found the error. I was loading thing more than once. I complitely forgot that Spring would load things for me and I was loading then by hand.
    Here's the solution the problem. I still need help with the test cases. How should I create and drop the tables??.. I would like to run the test as many times i want without falling into a DUPLICATE KEY exception or somethig like that..Thanks in advance.

    DBHelper - Helps me crete and drop the tables in the testcases so I can run over and over again, while
    making modifications to fit the desire logic.

    Code:
    public class DbHelper extends JdbcDaoSupport &#123;
    	public DbHelper&#40;&#41; &#123;
       	this.setDataSource&#40;ResourceManager.getDataSource&#40;&#41;&#41;;
    	&#125;
    &#125;
    The implementation of the interface ProductDao

    Code:
    public class ProductDaoImpl extends SqlMapClientDaoSupport implements ProductDao &#123; 
    	/** 
        * All finder methods in this class use this SELECT constant to build their queries
        */
        protected final String SQL_SELECT = "SELECT ID, DESCRIPTION FROM " + getTableName&#40;&#41; + "";
       /** 
        * SQL INSERT statement for this table
        */
        protected final String SQL_INSERT = "INSERT INTO " + getTableName&#40;&#41; + " &#40; ID, DESCRIPTION &#41; VALUES &#40; ?, ? &#41;";
       /**
        * Logger
        */
        protected static final Logger logger = Logger.getLogger&#40; ProductDaoImpl.class &#41;;
       
       /* Inserts a new row in the PRODUCTS table.
        * @see com.mycompany.framework.dao.core.Dao#insert&#40;java.lang.Object&#41;
        */
        public Object insert&#40;Object dto&#41; throws mycompanyDataAccessException &#123;
        	Product product = &#40;Product&#41; dto;
          if &#40;logger.isDebugEnabled&#40;&#41;&#41; &#123;
          	logger.debug&#40; "Executing " + SQL_INSERT + " with DTO&#58; " + product&#41;;
          &#125;
          this.getSqlMapClientTemplate&#40;&#41;.update&#40;"insertProduct", product &#41;;
          return product.createPk&#40;&#41;;
        &#125;
      
        /* Returns the rows from the PRODUCTS table that matches the specified primary-key value.
         * @see com.mycompany.framework.dao.core.Dao#findByPrimaryKey&#40;java.lang.Object&#41;
         */
        public Object findByPrimaryKey&#40;Object pk&#41; throws mycompanyDataAccessException &#123;
        	ProductPk productpk = &#40;ProductPk&#41; pk;
          if &#40;logger.isDebugEnabled&#40;&#41;&#41; &#123;
          	logger.debug&#40; "Executing " + SQL_SELECT + " with userPk&#58; " + productpk&#41;;
         	&#125;
          List ret = this.getSqlMapClientTemplate&#40;&#41;.queryForList&#40;"getProduct", pk &#41;;
          return &#40;Product&#41; &#40;ret.size&#40;&#41;==0 ? null &#58; ret.get&#40;0&#41;&#41;;
        &#125;
    
        /**
         * Method 'getTableName'
         * @return String
         */
         public String getTableName&#40;&#41; &#123;
            return "Referencia.PRODUCTS";
         &#125;
    &#125;
    Product.xml

    Code:
    <?xml version='1.0'?>
    
    <!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN"
            "http&#58;//www.ibatis.com/dtd/sql-map-2.dtd">
    
    <sqlMap namespace="Products">
    	<cacheModel id="products-cache" type="MEMORY">
       	<flushInterval hours="24"/>
          <flushOnExecute statement="insertProduct"/>
          <flushOnExecute statement="updateProduct"/>
          <flushOnExecute statement="deleteProduct"/>
          <property name="reference-type" value="WEAK" />
    	</cacheModel>
            
       <typeAlias alias="product" type="com.mycompany.sample.persistence.jdbc.dto.Product" />
       <typeAlias alias="productPk" type="com.mycompany.sample.persistence.jdbc.dto.ProductPk" />
    
       <resultMap class="product" id="product-result" >
       	<result property="id" column="ID" />
          <result property="description" column="DESCRIPTION" />
    	</resultMap>
    
    	<select id="getProduct" resultClass="product" parameterClass="productPk" resultMap="product-result" >
       	<!&#91;CDATA&#91;
          	select * from Referencia.PRODUCTS 
             where ID = #id#
           &#93;&#93;>
    	</select>
    
       <update id="updateProduct" parameterClass="product" >
       	<!&#91;CDATA&#91;
             update Referencia.PRODUCTS
             set DESCRIPTION = #description#
             where ID = #id#
           &#93;&#93;>
    	</update>
    
       <insert id="insertProduct" parameterClass="product" >
       	<!&#91;CDATA&#91;
          	insert into Referencia.PRODUCTS&#40;ID, DESCRIPTION&#41;
             values&#40;#id#, #description#&#41;
           &#93;&#93;>
    	</insert>       
    
       <delete id="deleteProduct" parameterClass="productPk" >
       	<!&#91;CDATA&#91;
             delete from Referencia.PRODUCTS
             where ID = #id#
           &#93;&#93;>
    	</delete>
    </sqlMap>
    Test Case

    Code:
    public class ProductsDaoImpTest extends TestCase &#123;
    	public static void main&#40;String&#91;&#93; args&#41; &#123;
       	junit.textui.TestRunner.run&#40;ProductsDaoImpTest.class&#41;;
       &#125;
       /*
        * @see TestCase#setUp&#40;&#41;
        */
        protected void setUp&#40;&#41; throws Exception &#123;
       	  DbHelper dbh = new DbHelper&#40;&#41;;
            dbh.getJdbcTemplate&#40;&#41;.execute&#40;"CREATE TABLE PRODUCTS&#40;ID INTEGER NOT NULL PRIMARY KEY,DESCRIPTION VARCHAR&#40;250&#41; NOT NULL&#41;"&#41;;
            super.setUp&#40;&#41;;
        &#125;
    
        /*
         * @see TestCase#tearDown&#40;&#41;
         */
        protected void tearDown&#40;&#41; throws Exception &#123;
            DbHelper dbh = new DbHelper&#40;&#41;;
            dbh.getJdbcTemplate&#40;&#41;.execute&#40;"DROP TABLE PRODUCTS"&#41;;
            super.tearDown&#40;&#41;;
        &#125;
       
        /*
         * Class under test for Object findByPrimaryKey&#40;Object&#41;
         */
        public void testFindByPrimaryKeyObject&#40;&#41; &#123;
            // ProductDao dao = ProductDaoFactory.create&#40;&#41;;
            Product product = new Product&#40;&#41;;
            product.setId&#40;new Integer&#40;1&#41;&#41;;
            product.setDescription&#40;"Producto el orto"&#41;;
            ApplicationContext context = new FileSystemXmlApplicationContext&#40;"applicationContext-jdbc.xml"&#41;;
            ProductDaoImpl dao = &#40;ProductDaoImpl&#41; context.getBean&#40;"productDao"&#41;; 
            dao.insert&#40;product&#41;;
            System.out.println&#40;dao.findByPrimaryKey&#40;product.createPk&#40;&#41;&#41;&#41;;
        &#125;
    &#125;
    iBatis Configuration

    Code:
    <sqlMapConfig>
    
      <properties resource="jdbc.properties"/>
    
      <settings
        cacheModelsEnabled="true"
        enhancementEnabled="true"
        maxSessions="64"
        maxTransactions="8"
        maxRequests="128"/>
    
      <!--transactionManager type="JDBC">
        <dataSource type="SIMPLE">
          <property value="$&#123;jdbc.driverClassName&#125;" name="JDBC.Driver"/>
          <property value="$&#123;jdbc.url&#125;" name="JDBC.ConnectionURL"/>
          <property value="$&#123;jdbc.username&#125;" name="JDBC.Username"/>
          <property value="$&#123;jdbc.password&#125;" name="JDBC.Password"/>
          <property value="15" name="Pool.MaximumActiveConnections"/>
          <property value="15" name="Pool.MaximumIdleConnections"/>
          <property value="1000" name="Pool.MaximumWait"/>
        </dataSource>
      </transactionManager-->
       
      <sqlMap resource="com/mycompany/sample/persistence/jdbc/scripts/iBatis/Products.xml"/>
      
    </sqlMapConfig>
    Spring configuration

    Code:
    <beans>
            <!-- ========================= RESOURCE DEFINITIONS ========================= -->
            <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
                    <property name="location"><value>/bin/jdbc.properties</value></property>
            </bean>
            <!-- DataSource local que trajaba en cualquier entorno -->
            <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
                    <property name="driverClassName"><value>$&#123;jdbc.driverClassName&#125;</value></property>
                    <property name="url"><value>$&#123;jdbc.url&#125;</value></property>
                    <property name="username"><value>$&#123;jdbc.username&#125;</value></property>
                    <property name="password"><value>$&#123;jdbc.password&#125;</value></property>
            </bean>
            <!-- Mapping para la configuracion de iBatis -->
            <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
                    <property name="configLocation"><value>sql-map-config.xml</value></property>
            </bean>
              
            <bean id="productDao" class="com.mycompany.sample.persistence.jdbc.jdbc.ProductDaoImpl">
                    <property name="dataSource"><ref local="dataSource"/></property>
                    <property name="sqlMapClient"><ref local="sqlMapClient"/></property>
            </bean>
    </beans>

    Leave a comment:


  • Rod Johnson
    replied
    I'm not clear at what point exactly it loops? When the Spring context is coming up? What environment do you run that test code in? Can you reproduce the endless loop without Spring configuration involved at all?

    Leave a comment:

Working...
X