Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: AbstractTransactionalDataSourceSpringContextTests , while writing a delete test.

  1. #1

    Default AbstractTransactionalDataSourceSpringContextTests , while writing a delete test.

    I've been using the mock test cases for awhile now..i never got it to work for deleting however...can somone shead some light into this??? im sure its because the transiaction is not being commited..but is there a work around??

    the second assert fails.

    test case does not work:

    Code:
    public void testDelete() {
    		Category category =createMockCategory();
    		categoryDAO.save(category);
    		assertTrue("Should be 1, we added 1 categories, instead we have [" + Integer.toString( jdbcTemplate.queryForList("SELECT * from CATEGORIES").size() ) + "]" ,jdbcTemplate.queryForList("SELECT * from CATEGORIES").size() == 1);
    		categoryDAO.delete(category);		
    		assertTrue("Should be 0, we deleted 1 categories, instead we have [" + Integer.toString( jdbcTemplate.queryForList("SELECT * from CATEGORIES").size() ) + "]" ,jdbcTemplate.queryForList("SELECT * from CATEGORIES").size() == 0);
    	}
    i am using hsqld for testing mysql for production(doesnt work in test case for either datasource).
    /^\\ Pharaoh /^\\
    http://pharaohofkush.blogspot.com/

    Jeryl Cook

  2. #2
    Join Date
    Aug 2004
    Posts
    1,905

    Default

    We need a bit more information first

    If you are using hibernate, it is probably caching the SQL selects until it absolutely has to (although I think deletes followed by a read should cause it to flush ). If this is the case try executing a session.flush() before the read. This will cause hibernate to send the SQL statements to the database.

    Is you DAO hibernate backed, or JDBC? Where are you transaction boundaries? I presume around each DAO method?

  3. #3

    Default

    i am using HibernateDAOSupport throughout.. i am not accessing the session directory(nor do i want to)..

    in a normal testCase(without the mocktransaction) it works fine.

    CategoryDAOImpl
    Code:
    public class CategoryDAOImpl
    extends HibernateDaoSupport
    implements ICategoryDAO{
    
    	/* (non-Javadoc)
    	 * @see com.vanitysoft.griffin.domain.hibernate.dao.ICategoryDAO#save(de.nava.informa.impl.hibernate.Category)
    	 */
    	public void save(Category category) {
    		getHibernateTemplate().save(category);
    	}
    
    	/* (non-Javadoc)
    	 * @see com.vanitysoft.griffin.domain.hibernate.dao.ICategoryDAO#delete(de.nava.informa.impl.hibernate.Category)
    	 */
    	public void delete(Category category) {
    		getHibernateTemplate().delete(category);
    	}
    
    	/* (non-Javadoc)
    	 * @see com.vanitysoft.griffin.domain.hibernate.dao.ICategoryDAO#findAll()
    	 */
    	public List findAll() {
    		return getHibernateTemplate().loadAll(Category.class);
    	}
    
    }
    context
    Code:
    <beans>
    	<bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean" singleton="true" lazy-init="default" autowire="default" dependency-check="default">
    	 <property name="dataSource"><ref bean="dataSource"/></property>	
    		<!-- Must references all OR mapping files. -->
    		<property name="mappingResources">
    			<list>
    				<value>de/nava/informa/impl/hibernate/Category.hbm.xml</value>
    				<value>de/nava/informa/impl/hibernate/Channel.hbm.xml</value>
    				<value>de/nava/informa/impl/hibernate/ChannelGroup.hbm.xml</value>
    				<value>de/nava/informa/impl/hibernate/ChannelSubscription.hbm.xml</value>
    				<value>de/nava/informa/impl/hibernate/Cloud.hbm.xml</value>
    				<value>de/nava/informa/impl/hibernate/Image.hbm.xml</value>
    				<value>de/nava/informa/impl/hibernate/Item.hbm.xml</value>
    				<value>de/nava/informa/impl/hibernate/ItemEnclosure.hbm.xml</value>
    				<value>de/nava/informa/impl/hibernate/ItemGuid.hbm.xml</value>
    				<value>de/nava/informa/impl/hibernate/ItemMetadata.hbm.xml</value>
    				<value>de/nava/informa/impl/hibernate/ItemSource.hbm.xml</value>
    				<value>de/nava/informa/impl/hibernate/TextInput.hbm.xml</value>	
     		        <value>com/vanitysoft/griffin/domain/hibernate/Authority.hbm.xml</value> 
    		        <value>com/vanitysoft/griffin/domain/hibernate/User.hbm.xml</value> 
    			</list>
    		</property>
    		 <property name="hibernateProperties">
    			<props>
    		 	    <prop key="hibernate.dialect">net.sf.hibernate.dialect.MySQLDialect</prop>
    				<prop key="hibernate.show_sql">true</prop>			 
    				<prop key="hibernate.cglib.use_reflection_optimizer">true</prop> 
    			    <prop key="hibernate.cache.provider_class">net.sf.hibernate.cache.EhCacheProvider</prop>  
    			    <prop key="hibernate.cache.use_query_cache">true</prop>
    				<prop key="hibernate.hbm2ddl.auto">update</prop> 
    			</props>
    		</property>
    	</bean>
    
    	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    			<property name="driverClass"><value>org.gjt.mm.mysql.Driver</value></property>
      			<property name="jdbcUrl"><value>jdbc:mysql://localhost:3306/griffin?</value></property>
       			<property name="user"><value>root</value></property>
       			<property name="password"><value></value></property>
       			<property name="maxPoolSize"><value>100</value></property>
       			<property name="maxStatements"><value>100</value></property>	
    			<property name="autoCommitOnClose"><value>true</value></property>		
    	 </bean>

    daoContext.xml
    Code:
    <beans>
    
      <!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) , changed singleton to true, 10.10.04-->
    	 <bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager" singleton="true" lazy-init="default" autowire="default" dependency-check="default">
           <property name="sessionFactory"><ref bean="sessionFactory"/></property>
        </bean>
        
    	<!-- ========================= Start of PERSISTENCE DEFINITIONS ========================= -->  
    
    				<!-- DAO object:  -->
    		<bean id="userDAO" class="com.vanitysoft.griffin.domain.hibernate.dao.impl.UserDAOImpl">
    			<property name="sessionFactory"><ref bean="sessionFactory"/></property>
    		</bean>
    
    		 <bean id ="channelDAO" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">			
    			<property name="transactionManager"><ref bean="transactionManager"/></property>
    			 <property name="target">
    		 		<bean class="com.vanitysoft.griffin.domain.hibernate.dao.impl.ChannelDAOImpl">
    					<property name="sessionFactory"><ref bean="sessionFactory"/></property>
    				</bean>
    			</property>
    			<property name="transactionAttributes">
    				<props>
              			<prop key="save*">PROPAGATION_REQUIRED</prop>
              			<prop key="replace*">PROPAGATION_REQUIRED</prop>
              			<prop key="delete*">PROPAGATION_REQUIRED</prop>
    					<prop key="import*">PROPAGATION_REQUIRED</prop>
    				</props>
    			</property>
    		</bean>  
    
    		 <bean id="itemDAO" class="com.vanitysoft.griffin.domain.hibernate.dao.impl.ItemDAOImpl">
    			<property name="sessionFactory"><ref bean="sessionFactory"/></property>
    		</bean>
    		 <bean id="categoryDAO" class="com.vanitysoft.griffin.domain.hibernate.dao.impl.CategoryDAOImpl">
    			<property name="sessionFactory"><ref bean="sessionFactory"/></property>
    		</bean>
    		 <bean id="itemEnclosureDAO" class="com.vanitysoft.griffin.domain.hibernate.dao.impl.ItemEnclosureDAOImpl">
    			<property name="sessionFactory"><ref bean="sessionFactory"/></property>
    		</bean>
    </beans>

    thanks for the quick response.
    Last edited by twoencore; Jan 23rd, 2006 at 11:52 AM.
    /^\\ Pharaoh /^\\
    http://pharaohofkush.blogspot.com/

    Jeryl Cook

  4. #4
    Join Date
    Aug 2004
    Posts
    1,905

    Default

    Ah, a fellow Eclipse man

    Where are you *doing* the transaction demarcation, in code, or in the XML?

    And what do you mean by "mock" transaction? If you are talking about the test class you are abstracting, it doesn't use "mock" transactions, it uses actual transactions. When you say it works fine without using the mock transactions, what do you mean?

    By default, it won't commit unless you tell it to by setting setComplete? (read the docs; I cannot remember).

    You are right not to want to touch the hibernate session, but sometimes you need to *in the test* because Hibernate caches SQL statements for as long as it can, so sometimes you need to manually flush, but as I say, this is usually a side effect of the way the tests work.

    Hmm. Odd. Even though the transaction isn't being flushed I would still expect the deletion to be visible (to the same transaction).

    Could you step through and confirm that the delete SQL is being issued before the dao.load method....

  5. #5

    Default

    took me 2 minutes, but i got it..sup eclipse man

    i meant 'mock' only in the sense i am using spring-mock.jar.. where am extending the AbstractTransactionalDataSourceSpringContextTests , so it will auto-rollback database changes in my testcases..

    i am not wrapping the transactions for delete yet..i plan to do it in the .xml file.. just like i did the ChannelDAO..

    i debugged, i dont see delete every being called..(??)
    however in a normal test case i see the delete being called.


    here is my full test code.

    Code:
    /**
     * @author Jeryl Cook
     *
     */
    public abstract class AbstractDAO
    	extends AbstractTransactionalDataSourceSpringContextTests{
    	protected ICategoryDAO categoryDAO = null;
    	
    public void setCategoryDAO(ICategoryDAO categoryDAO) {
    		this.categoryDAO = categoryDAO;
    	}
    
    	/**
    	 * @return
    	 */
    	public static Category createMockCategory() {
    		Category category = new Category();
    		category.setTitle("Arts & Entertainment");
    		return category;
    	}
    }
    CategoryDAOTest
    Code:
    public class CategoryDAOTest extends AbstractDAO {
     
    	public void testDelete() {
    
    		Category category = new Category();
    		category.setTitle("Arts & Entertainment");
    		categoryDAO.save(category);
    		assertTrue("Should be 1, we added 1 categories, instead we have [" + Integer.toString( jdbcTemplate.queryForList("SELECT * from CATEGORIES").size() ) + "]" ,jdbcTemplate.queryForList("SELECT * from CATEGORIES").size() == 1);
    		categoryDAO.delete(category);		
    		assertTrue("Should be 0, we deleted 1 categories, instead we have [" + Integer.toString( jdbcTemplate.queryForList("SELECT * from CATEGORIES").size() ) + "]" ,jdbcTemplate.queryForList("SELECT * from CATEGORIES").size() == 0);
     
    	}
    
    	/* (non-Javadoc)
    	 * @see org.springframework.test.AbstractDependencyInjectionSpringContextTests#getConfigLocations()
    	 */
    	protected String[] getConfigLocations() {
    		return new String[]{"/daoContext.xml","/datasource.xml"};
    /^\\ Pharaoh /^\\
    http://pharaohofkush.blogspot.com/

    Jeryl Cook

  6. #6
    Join Date
    Aug 2004
    Posts
    1,905

    Default

    Hmmm, and I am assuming daoContext + dataSource don't do any transaction declaration.

    In this case, if the delete SQL is not being updated, try (just to eliminate) doing a session.flush() in the DAO (yes I know, hold you horses ).

    See if that works?

    Also, it might get real confusing really quickly if you name your test AbstractDAO

  7. #7
    Join Date
    May 2005
    Posts
    208

    Default

    Quote Originally Posted by twoencore
    I've been using the mock test cases for awhile now..i never got it to work for deleting however...can somone shead some light into this??? im sure its because the transiaction is not being commited..but is there a work around??

    the second assert fails.

    test case does not work:

    Code:
    public void testDelete() {
    		Category category =createMockCategory();
    		categoryDAO.save(category);
    		assertTrue("Should be 1, we added 1 categories, instead we have [" + Integer.toString( jdbcTemplate.queryForList("SELECT * from CATEGORIES").size() ) + "]" ,jdbcTemplate.queryForList("SELECT * from CATEGORIES").size() == 1);
    		categoryDAO.delete(category);		
    		assertTrue("Should be 0, we deleted 1 categories, instead we have [" + Integer.toString( jdbcTemplate.queryForList("SELECT * from CATEGORIES").size() ) + "]" ,jdbcTemplate.queryForList("SELECT * from CATEGORIES").size() == 0);
    	}
    i am using hsqld for testing mysql for production(doesnt work in test case for either datasource).
    I just suffered through this very problem:

    http://forum.springframework.org/showthread.php?t=21481
    http://forum.springframework.org/showthread.php?t=18263

    The first thread lays out my plight. The second thread was the true solution that's working as advertised now. I hope these help you, too.

    %

  8. #8
    Join Date
    May 2005
    Posts
    208

    Default

    I disagree with the use of mocks in this case. If you're doing what I was, I really want to touch the database. I'd only consider mocks if I'd successfully tested the DAOs and had moved on to the service layer. In that case I might mock the DAOs so I could concentrate on testing just the service layer.

    %

  9. #9
    Join Date
    Aug 2004
    Posts
    1,905

    Default

    Quote Originally Posted by duffymo
    I disagree with the use of mocks in this case. If you're doing what I was, I really want to touch the database. I'd only consider mocks if I'd successfully tested the DAOs and had moved on to the service layer. In that case I might mock the DAOs so I could concentrate on testing just the service layer.

    %
    I don't think the OP is actually using mock objects in the sense you mean

    twoencore: you do need to do a flush so Hibernate will execute the SQL.

  10. #10

    Default got it. thx

    thanks

    yatesco and duffymo(say this 5 times very fast).

    i implemented flush in my AbstractDAO(test abstractDAO )
    and called flush soon after i .delete(), and the unit test worked. this should really be documented for people who use the AbstractTransactionalDataSourceSpringContextTests classes in spring-mock... because outside the test in 'live' application it works find without calling .flush()...


    abstractDAO(should be AbstractDAOTest)
    Code:
    public abstract class AbstractDAO
    	extends AbstractTransactionalDataSourceSpringContextTests{
    	 
                 protected ICategoryDAO categoryDAO = null;
     
    	private SessionFactory sessionFactory = null;
    	
    	private HibernateTemplate hibernateTemplate;
    	 
          protected void flush() {
    	        //Initialize Hibernate Template if Necessary
    	        if(hibernateTemplate == null) {
    	            hibernateTemplate = new HibernateTemplate(sessionFactory);
    	        }
    	        hibernateTemplate.flush();
    	   }
    
    	public void setCategoryDAO(ICategoryDAO categoryDAO) {
    		this.categoryDAO = categoryDAO;
    	}
    
    	public void setSessionFactory(SessionFactory sessionFactory) {
    		this.sessionFactory = sessionFactory;
    	}
    in the modified testDelete method in CategoryDAOTest

    Code:
    /**
     * @author Jeryl Cook
     *
     */
    public class CategoryDAOTest
    	extends AbstractDAO {
    
    	/**
    	 * @param name
    	 */
    	public CategoryDAOTest(String name) {
    		super(name);
    		// TODO Auto-generated constructor stub
    	}
    
    	public void testDelete() {
    
    		Category category = new Category();
    		category.setTitle("Arts & Entertainment");
    		categoryDAO.save(category);
    		assertTrue("Should be 1, we added 1 categories, instead we have [" + Integer.toString( jdbcTemplate.queryForList("SELECT * from CATEGORIES").size() ) + "]" ,jdbcTemplate.queryForList("SELECT * from CATEGORIES").size() == 1);
    		categoryDAO.delete(category);	
    		flush();
    		assertTrue("Should be 0, we deleted 1 categories, instead we have [" + Integer.toString( jdbcTemplate.queryForList("SELECT * from CATEGORIES").size() ) + "]" ,jdbcTemplate.queryForList("SELECT * from CATEGORIES").size() == 0);
     
    	}
    
    	/* (non-Javadoc)
    	 * @see org.springframework.test.AbstractDependencyInjectionSpringContextTests#getConfigLocations()
    	 */
    	protected String[] getConfigLocations() {
    		return new String[]{"/daoContext.xml","/datasource-junit.xml"};
    	}

    thx yall.
    /^\\ Pharaoh /^\\
    http://pharaohofkush.blogspot.com/

    Jeryl Cook

Posting Permissions

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