More weirdness with dataContext invalidateObjects()

From: Mike Kienenberger (mkienen..laska.net)
Date: Fri Sep 10 2004 - 20:30:13 EDT

  • Next message: Andrus Adamchik: "Re: [off topic] XMLGUI"

    This isn't directly related to my last problem with rollbackChanges().

    I'm writing unit tests for my Struts application. So I can't easily (nor
    do I really want to) create a new DataContext for each test. However, my
    DataContext is "remembering" data between tests. My test setup() includes
    these values as the last two lines, which I had hoped would wipe clean the
    DataContext.

                    // delete and recreate all existing data via non-cayenne methods
            dbunit.executeOperation(DatabaseOperation.DELETE_ALL,
    targetUserDataSet);
            cleanInsertStandardUsers();
            dbunit.executeOperation(DatabaseOperation.REFRESH,
    targetUserDataSet);

                    // wipe clean cayenne data context
            getDataContext().rollbackChanges();
            
    getDataContext().invalidateObjects(getDataContext().getObjectStore().getObjects());

    After this point, all data is refetched from the database using
    DataContext.performQuery(query).
    However, I'm getting optimistic locking failures when I try to run a test.
    The data in the problem object matches what was updated in the last test
    rather than what's in the database!

                    // generatePaymentMethodsList uses
    selectedUserBefore.getDataContext().performQuery() to fetch the data
            List paymentMethodListBefore =
    PaymentMethod.generatePaymentMethodsList(primaryAccountBefore,
    selectedUserBefore);

            PaymentMethod paymentMethod =
    (PaymentMethod)paymentMethodListBefore.get(0);
            // 1)
    getDataContext().invalidateObjects(getDataContext().getObjectStore().getObjects());
            CreditCard creditCard = paymentMethod.getCreditCard();
            // 2)
    getDataContext().invalidateObjects(getDataContext().getObjectStore().getObjects());

            Calendar creditCadExpirationDateCalendar = Calendar.getInstance();
            
    creditCard.setCreditCardExpirationDate(creditCadExpirationDateCalendar.getTime());

            getDataContext().commitChanges();

    Here's what I don't understand:
    If I call invalidateObjects at or before point 1), the old creditCard data
    is used.
    If I call invalidateObjects at point 2, the creditCard data is refetched
    from the database.

    A little bit more testing shows that if I use the following code -- even as
    the first lines of my setup() -- the problem also goes away.

            getDataContext().rollbackChanges();
            
    getDataContext().invalidateObjects(getDataContext().getObjectStore().getObjects());
            getDataContext().getObjectStore().getDataRowCache().clear();

    I have no idea if user code should be calling
    getDataContext().getObjectStore().getDataRowCache().clear(), nor why this
    works and not invalidateObjects(). Hopefully the answer to the last
    question is the key to my understanding of the nature of the problem. :)

    I kinda feel like I'm killing a gnat with a nuclear bomb.

    -Mike



    This archive was generated by hypermail 2.0.0 : Fri Sep 10 2004 - 20:29:26 EDT