-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 
Author Message
 Post subject: Spring/Hibernate/JUnit Cascade issue
PostPosted: Mon Jan 26, 2009 12:32 pm 
Newbie

Joined: Wed Oct 01, 2008 8:42 pm
Posts: 12
Version Info:
Hibernate 3.2.6GA
Spring 2.5.5
JUnit 4.4.

Name and version of the database you are using:
Oracle 10G

Mapping documents:
Classes in question:
Code:
public class Requisition {
   @Id @GeneratedValue(generator="increment")
   @Column(name="REQ_NUMBER")
   private Integer requisitionNumber;
   
   @ManyToOne(fetch=FetchType.LAZY)
   @JoinColumn(name="REQ_TYPE", referencedColumnName="VALUE")
   private RequisitionType requisitionType;
   
   @Column(name="USER_ID")
   private String userId;
   
   @OneToMany(mappedBy="requisition", fetch=FetchType.LAZY, cascade=CascadeType.ALL)
   private List<RequisitionOrder> orders;


etc.

Code:
public class RequisitionOrder {
   @Id @GeneratedValue(generator="increment")
   @Column(name = "ORDER_NUMBER")
   private Integer orderNumber;
   @ManyToOne(fetch=FetchType.LAZY)
   @JoinColumn(name = "REQ_NUMBER")
   private Requisition requisition;
   @Column(name = "REQ_STATUS")
   private String status;


etc.

Test class:

Code:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath*:context/core-context.xml", "/context/orders/testRequisition-context.xml"})
@TransactionConfiguration(transactionManager="txManager", defaultRollback=true)
@Transactional
public class TestRequisitionOrder {
   @Resource
   private SessionFactory sessionFactory;
   
   @Resource
   private RequisitionDao requisitionDao;
   @Resource
   private RequisitionOrderDao requisitionOrderDao;
   @Resource
   private LoginUserDao loginUserDao;
   @Resource
   private RequisitionTypeDao requistionTypeDao;
   
   //Test objects
   @Resource
   private RequisitionType testRequisitionTypeA;
   @Resource
   private RequisitionType testRequisitionTypeB;
   @Resource
   private Requisition testRequisitionA;
   @Resource
   private Requisition testRequisitionB;
   @Resource
   private LoginUser testUserA;
   
   @Before
    public void setUpTestDataWithinTransaction() throws Exception{
        // set up test data within the transaction
      
      testUserA.setActiveDate(new Date());
      loginUserDao.save(testUserA);
      requistionTypeDao.save(testRequisitionTypeA);   
      requistionTypeDao.save(testRequisitionTypeB);      
      requisitionDao.save(testRequisitionA);
      requisitionDao.save(testRequisitionB);
    }
      
   @Test
   public void testFindById(){
      RequisitionOrder order = requisitionOrderDao.findByID(requisitionOrderDao.getHighestID());
      Assert.assertEquals("TEST ORDER C", order.getReason());
   }
   
   @Test
   public void testFindByStatus(){
      List<RequisitionOrder> orders = requisitionOrderDao.findByStatus("O");
      Assert.assertEquals(1, orders.size());
      
      List<String> statuses = new ArrayList<String>();
      statuses.add("O");
      statuses.add("R");
      
      List<RequisitionOrder> orders2 = requisitionOrderDao.findByStatus(statuses);
      Assert.assertEquals(2, orders2.size());
   }




The issue:
In the Unit test I'm creating some fake requisitions with orders that are configured as spring beans in XML. I am then taking these objects and saving them before the test, and rolling them back after each test, so that no data is committed inside of it.

In the test I have above, the first case works fine. The following SQL is generated to set up my test objects before I call "findById" in my test:

Code:
Hibernate: insert into REQUISITION_TYPES (DESCRIPTION, NAME, VALUE) values (?, ?, ?)
Hibernate: insert into REQUISITION_TYPES (DESCRIPTION, NAME, VALUE) values (?, ?, ?)
Hibernate: insert into REQUISITION_TABLE (REQ_TYPE, USER_ID, REQ_NUMBER) values (?, ?, ?)
Hibernate: insert into REQUISITION_ORDER_TABLE (ADJUSTMENT, COMPLETE_DATE, COST, ORDERED_DATE, OVERHEAD, REASON, RECONCILED_DATE, REQ_NUMBER, REQ_STATUS, TOTAL_COST, ORDER_NUMBER) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into REQUISITION_ORDER_TABLE (ADJUSTMENT, COMPLETE_DATE, COST, ORDERED_DATE, OVERHEAD, REASON, RECONCILED_DATE, REQ_NUMBER, REQ_STATUS, TOTAL_COST, ORDER_NUMBER) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into REQUISITION_TABLE (REQ_TYPE, USER_ID, REQ_NUMBER) values (?, ?, ?)
Hibernate: insert into REQUISITION_ORDER_TABLE (ADJUSTMENT, COMPLETE_DATE, COST, ORDERED_DATE, OVERHEAD, REASON, RECONCILED_DATE, REQ_NUMBER, REQ_STATUS, TOTAL_COST, ORDER_NUMBER) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)



And the test passes as expected.

However, on the second test, the following SQL is generated:

Code:
Hibernate: insert into REQUISITION_TYPES (DESCRIPTION, NAME, VALUE) values (?, ?, ?)
Hibernate: insert into REQUISITION_TYPES (DESCRIPTION, NAME, VALUE) values (?, ?, ?)
Hibernate: insert into REQUISITION_TABLE (REQ_TYPE, USER_ID, REQ_NUMBER) values (?, ?, ?)
Hibernate: insert into REQUISITION_TABLE (REQ_TYPE, USER_ID, REQ_NUMBER) values (?, ?, ?)
Hibernate: update REQUISITION_ORDER_TABLE set ADJUSTMENT=?, COMPLETE_DATE=?, COST=?, ORDERED_DATE=?, OVERHEAD=?, REASON=?, RECONCILED_DATE=?, REQ_NUMBER=?, REQ_STATUS=?, TOTAL_COST=? where ORDER_NUMBER=?
Hibernate: update REQUISITION_ORDER_TABLE set ADJUSTMENT=?, COMPLETE_DATE=?, COST=?, ORDERED_DATE=?, OVERHEAD=?, REASON=?, RECONCILED_DATE=?, REQ_NUMBER=?, REQ_STATUS=?, TOTAL_COST=? where ORDER_NUMBER=?
Hibernate: update REQUISITION_ORDER_TABLE set ADJUSTMENT=?, COMPLETE_DATE=?, COST=?, ORDERED_DATE=?, OVERHEAD=?, REASON=?, RECONCILED_DATE=?, REQ_NUMBER=?, REQ_STATUS=?, TOTAL_COST=? where ORDER_NUMBER=?


The problem here is that rather than inserting new orders under the requisition, it's trying to update a non-existent one. The second test fails as a result. Can anyone explain why this is happening?

It seems like hibernate thinks the orders are already persisted (even though the previous transaction was rolled back) and is then trying to update it instead of inserting a new one. What I don't understand is why the same thing doesn't happen with the requisition itself. Something to do with the cascade perhaps?

If I put these two tests in separate class files with the same @Before and context config, everything works fine.

Also should note that I'm relatively new to writing unit tests so if I'm making some huge design mistake please let me know.

Thanks,
Tim


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.