Transaction issue in java with hibernate - latest entries not pulled from database

Posted by Gearóid on Stack Overflow See other posts from Stack Overflow or by Gearóid
Published on 2010-03-19T10:20:23Z Indexed on 2010/03/19 11:11 UTC
Read the original article Hit count: 268

Filed under:
|
|

Hi,

I'm having what seems to be a transactional issue in my application. I'm using Java 1.6 and Hibernate 3.2.5.

My application runs a monthly process where it creates billing entries for a every user in the database based on their monthly activity. These billing entries are then used to create Monthly Bill object. The process is:

  1. Get users who have activity in the past month
  2. Create the relevant billing entries for each user
  3. Get the set of billing entries that we've just created
  4. Create a Monthly Bill based on these entries

Everything works fine until Step 3 above. The Billing Entries are correctly created (I can see them in the database if I add a breakpoint after the Billing Entry creation method), but they are not pulled out of the database. As a result, an incorrect Monthly Bill is generated.

If I run the code again (without clearing out the database), new Billing Entries are created and Step 3 pulls out the entries created in the first run (but not the second run). This, to me, is very confusing.

My code looks like the following:

for (User user : usersWithActivities) {

            createBillingEntriesForUser(user.getId());

            userBillingEntries = getLastMonthsBillingEntriesForUser(user.getId());

            createXMLBillForUser(user.getId(), userBillingEntries);
    }

The methods called look like the following:

@Transactional
    public void createBillingEntriesForUser(Long id) {

        UserManager userManager = ManagerFactory.getUserManager();
        User user = userManager.getUser(id);
        List<AccountEvent> events = getLastMonthsAccountEventsForUser(id);
        BillingEntry entry = new BillingEntry();

        if (null != events) {

            for (AccountEvent event : events) {

                if (event.getEventType().equals(EventType.ENABLE)) {
                    Calendar cal = Calendar.getInstance();

                    Date eventDate = event.getTimestamp();
                    cal.setTime(eventDate);

                    double startDate = cal.get(Calendar.DATE);
                    double numOfDaysInMonth = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
                    double numberOfDaysInUse = numOfDaysInMonth - startDate;

                    double fractionToCharge = numberOfDaysInUse/numOfDaysInMonth;

                    BigDecimal amount = BigDecimal.valueOf(fractionToCharge * Prices.MONTHLY_COST);
                    amount.scale();
                    entry.setAmount(amount);
                    entry.setUser(user);
                    entry.setTimestamp(eventDate);

                    userManager.saveOrUpdate(entry);
                }


            }

        }

    }


@Transactional
    public Collection<BillingEntry> getLastMonthsBillingEntriesForUser(Long id) {

        if (log.isDebugEnabled())
            log.debug("Getting all the billing entries for last month for user with ID " + id);

        //String queryString = "select billingEntry from BillingEntry as billingEntry where billingEntry>=:firstOfLastMonth and billingEntry.timestamp<:firstOfCurrentMonth and billingEntry.user=:user";
        String queryString = "select be from BillingEntry as be join be.user as user where user.id=:id and be.timestamp>=:firstOfLastMonth and be.timestamp<:firstOfCurrentMonth";

        //This parameter will be the start of the last month ie. start of billing cycle
        SearchParameter firstOfLastMonth = new SearchParameter();
        firstOfLastMonth.setTemporalType(TemporalType.DATE);

        //this parameter holds the start of the CURRENT month - ie. end of billing cycle
        SearchParameter firstOfCurrentMonth = new SearchParameter();
        firstOfCurrentMonth.setTemporalType(TemporalType.DATE);

        Query query = super.entityManager.createQuery(queryString);

        query.setParameter("firstOfCurrentMonth", getFirstOfCurrentMonth());        
        query.setParameter("firstOfLastMonth", getFirstOfLastMonth());
        query.setParameter("id", id);

        List<BillingEntry> entries = query.getResultList();

        return entries;
    }

public MonthlyBill createXMLBillForUser(Long id, Collection<BillingEntry> billingEntries) {

        BillingHistoryManager manager = ManagerFactory.getBillingHistoryManager();
        UserManager userManager = ManagerFactory.getUserManager();

        MonthlyBill mb = new MonthlyBill();
        User user  = userManager.getUser(id);

        mb.setUser(user);
        mb.setTimestamp(new Date());

        Set<BillingEntry> entries = new HashSet<BillingEntry>();
        entries.addAll(billingEntries);

        String xml = createXmlForMonthlyBill(user, entries);
        mb.setXmlBill(xml);
        mb.setBillingEntries(entries);
        MonthlyBill bill = (MonthlyBill) manager.saveOrUpdate(mb);
        return bill;

    }

Help with this issue would be greatly appreciated as its been wracking my brain for weeks now!

Thanks in advance, Gearoid.

© Stack Overflow or respective owner

Related posts about java

Related posts about hibernate