Results 1 to 10 of 10

Thread: Transaction propagation in unit tests.

  1. #1
    Join Date
    Jul 2006
    Posts
    126

    Default Transaction propagation in unit tests.

    Hi,

    I am creating a test cases for my spring services used with EclipseLink JPA.

    I am extending from AbstractJpaTests. I am using two services within a single test wherein one service inserts some data and another service retrieves the data.

    AFAIK the transactions done within tests are rolled back after the test case is over. However within a test case various service methods participating in the transaction should join the same transaction otherwise it wouldn't get the data changes done by the previous service method call.

    However in my case the second service is not able to see the data. I am sure it's in a different transaction than the original one. But I am not able to figure out how.

    Could somebody please help me here?

    My test class looks like

    Code:
    @ContextConfiguration(locations = { "classpath:beans-config.xml" })
    public class TestClass extends AbstractJpaTests {
           ......
           ......	
            @Test
            public void test1(){
                   service1.save(aentity);   //   1
                   someClass.method1();
            }
    }
    
    public class SomeClass {
            public void method1(){
    //Here I am passing correct query and parameters for finding the //entity //inserted at 1
                   service1.findEntity(query, parameters);
                   //I get exception here for no result
            }
    }
    public class Service1 {
            @Transactional (readOnly = true, propagation = Propagation.REQUIRED)
            public void findEntity(String query, Object[] parameters){
                    ......
            }
    }
    Thanks in advance,
    Shashi

  2. #2
    Join Date
    Jul 2006
    Posts
    126

    Default

    Could somebody please suggest anything wrong here?

    Thanks in advance,
    Shashi

  3. #3
    Join Date
    Jul 2006
    Posts
    126

    Default

    Could somebody please reply?

    Thanks,
    Shashi

  4. #4
    Join Date
    Jan 2006
    Location
    Zürich, Switzerland
    Posts
    424

    Default

    Hi Shashi,

    I assume you are trying to use the Spring TestContext Framework we introduced in Spring 2.5, since you're using @ContextConfiguration. Thus, have your test class extend extend AbstractTransactionalJUnit4SpringContextTests instead of the old AbstractJpaTests class.

    Give that a try and see if that helps.

    Regards,

    Sam

    p.s. FYI: AbstractJpaTests is deprecated as of Spring 3.0. So that's another reason to move away from it.

  5. #5
    Join Date
    Mar 2006
    Posts
    7

    Default

    You can also try calling setComplete() and endTransaction() after you have inserted the data, I believe transactions roll back during unit tests unless you call this.

    Code:
    	
    public class EmployeeServiceIntegrationTest extends AbstractJpaTests {
    
    	protected void onSetUpInTransaction() throws Exception {
    		Employee emp1 = new Employee("0001", "Joe", "R", "Smith", "4853",
    				"Engineer", 3, 'M', 20000.00, 0.00, 0.00, new Address(10,
    				"Walker Street"), new Date(), new Date());
    
    		employeeService.save(emp1);
    
    		this.setComplete();
    		this.endTransaction();
    		
    	}
    }
    }

  6. #6
    Join Date
    Jan 2006
    Location
    Zürich, Switzerland
    Posts
    424

    Default

    Quote Originally Posted by Mike Carr View Post
    You can also try calling setComplete() and endTransaction() after you have inserted the data
    Please note that setComplete() and endTransaction() are only available in the legacy JUnit 3.8 Spring testing support (i.e., in subclasses of AbstractTransactionalSpringContextTests which is deprecated as of Spring 3.0 in favor of the Spring TestContext Framework).

    Quote Originally Posted by Mike Carr View Post
    I believe transactions roll back during unit tests unless you call this.
    That is correct: transactions roll back automatically by default for transactional tests, but see my comments below.

    Quote Originally Posted by Mike Carr View Post
    Code:
    	
    public class EmployeeServiceIntegrationTest extends AbstractJpaTests {
    
    	protected void onSetUpInTransaction() throws Exception {
    		Employee emp1 = new Employee("0001", "Joe", "R", "Smith", "4853",
    				"Engineer", 3, 'M', 20000.00, 0.00, 0.00, new Address(10,
    				"Walker Street"), new Date(), new Date());
    
    		employeeService.save(emp1);
    
    		this.setComplete();
    		this.endTransaction();		
    	}
    }
    }
    If for some reason you need to use the legacy JUnit 3.8 testing support, please note that you would actually want to do the above in onSetUpBeforeTransaction(), not in onSetUpInTransaction(). It does not make any sense to use onSetUpInTransaction() if you want to have the transaction committed immediately. Note also that there is a startNewTransaction() method in AbstractTransactionalSpringContextTests which you would typically want to use to ensure that a transaction is used for the remainder of the test.

    FYI: if you use onSetUpBeforeTransaction(), there would obviously be no need to call setComplete() or endTransaction().

    If you would like to see similar support added to the TestContext Framework, please vote for it in JIRA.

    Regards,

    Sam

  7. #7
    Join Date
    Mar 2006
    Posts
    7

    Default

    Thanks for the info, I will have to look into "Spring TestContext Framework" I have not used this.

  8. #8
    Join Date
    Jul 2006
    Posts
    126

    Default

    Thanks Sam, Thanks Mike,

    I will try using AbstractTransactionalJUnit4SpringContextTests and post my experience.

    Thanks,
    Shashi

  9. #9
    Join Date
    Mar 2006
    Posts
    7

    Default

    I keep battling this same problem, everytime I mess with the config I get an error.

    Here is my code:
    Code:
    package jpa.test.three.resource;
    
    import static org.junit.Assert.*;
    
    import javax.persistence.PersistenceContext;
    import javax.persistence.PersistenceUnit;
    
    import jpa.test.three.model.Customer;
    
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.apache.cxf.jaxrs.client.WebClient;
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    import org.springframework.test.context.transaction.TransactionConfiguration;
    
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations={"classpath:jpa-test-application-context.xml"})
    @TransactionConfiguration(transactionManager="transactionManager", defaultRollback=false)
    @PersistenceUnit(unitName="dwSpring2Jpa")
    public class CustomerJpaTest extends AbstractTransactionalJUnit4SpringContextTests  {
    
    	protected transient Log logger = LogFactory.getLog(getClass());
    	
    	@Test
    	public void testIt(){
    		logger.debug("Here we go");
    
    		WebClient client = WebClient.create("http://localhost:9000/");
    		client.path("/customers/customer");
    		
    		Customer cust1 = new Customer();
    		cust1.setName("John Doe");
    		cust1.setAddress("555 First Street");
    		cust1 = client.post(cust1, Customer.class);
    		assertEquals(client.getResponse().getStatus(),200);
    		assertNotNull(cust1);
    	}
    
    }
    Code:
    Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: Object: jpa.test.three.model.Customer@1daa156 is not a known entity type.; nested exception is java.lang.IllegalArgumentException: Object: jpa.test.three.model.Customer@1daa156 is not a known entity type.
    	at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:271)
    	at org.springframework.orm.jpa.DefaultJpaDialect.translateExceptionIfPossible(DefaultJpaDialect.java:120)
    	at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:212)
    	at org.springframework.orm.jpa.JpaAccessor.translateIfNecessary(JpaAccessor.java:152)
    	at org.springframework.orm.jpa.JpaTemplate.execute(JpaTemplate.java:189)
    	at org.springframework.orm.jpa.JpaTemplate.persist(JpaTemplate.java:266)
    	at jpa.test.three.service.impl.CustomerDaoJpa.save(CustomerDaoJpa.java:57)
    	at jpa.test.three.resource.CustomerResource.addCustomer(CustomerResource.java:41)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:597)
    	at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:166)
    	at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:82)
    	... 24 more

  10. #10
    Join Date
    Aug 2008
    Posts
    8

    Default

    Hi,

    Anyone has a solution to this.. I'm also running to bject: com.nostratech.maumobil.persistence.domain.Rim@3a3 f4a21 is not a known entity type after migrating away from AbstractJpaTests.

    Any pointer is appreciated.

Posting Permissions

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