Re: Composite objects

From: Derek Rendall (cayenn..sure.com)
Date: Wed Nov 10 2004 - 20:44:36 EST

  • Next message: Joćo Paulo Vasconcellos: "Re: cayenne.xml not found"

    ----- Original Message -----
    From: "Andrus Adamchik" <andru..bjectstyle.org>
    To: <cayenne-use..bjectstyle.org>
    Sent: Wednesday, November 10, 2004 5:21 PM
    Subject: Re: Composite objects

    > Hi Darek,
    >
    > There is a number of issues here. Some can be solved within current
    > Cayenne design, some - with custom wrapping of DataObjects, and some will
    > probably require enhancements to the Cayenne core. So lets see what we
    > have...
    >
    > On Nov 8, 2004, at 11:02 PM, Derek Rendall wrote:
    >> The first is basicaly the classic Address within Party where we have an
    >> object that wraps several attributes of the domain object in order to
    >> provide certain standardised functionality. Other examples include cases
    >> where we have several related attributes dealing with taxation etc. In
    >> this case we do not need to create these objects outside of the context
    >> of their parent.
    >
    > For this you can still map your DataObjects to the table structure, but
    > create wrapper methods on the "parent" object. In the future we will allow
    > "flattened" attributes just like we do allow flattened relationships now.
    > I believe a part of the backend for flattened attributes is already there,
    > but undocumented and untested (it was done some time ago by Andriy for a
    > specific case, but we never made it generic and official).

    Sounds interesting - any pointers to where to look - I might be able to get
    someone to check it out for us over the next couple of weeks? Don't worry if
    you are too busy with getting the nested editing context into the next
    release :-) as we could stick with changing the subclass for now.

    >
    >> The other case involves a class we created a class that wraps a
    >> BigDecimal. In our current data layer we translate attributes that are
    >> instances of this object to/from a BigDecimal in the database. We have a
    >> lot of complex code that uses this wrapping class, and I want to change
    >> things as little as possible. In this case, we do need to be able to
    >> create this object outside of its parent and assign it to an attribute
    >> on the parent.
    >>
    >> Is there a way to do either (similar to Hibernates User Objects/Types?),
    >> particularly the second case? If not, is such functionality planned
    >> anytime soon? If the answer is still no, what would be the best approach
    >> to try and implement such behaviour?
    >
    > Yes - ExtendedTypes in Cayenne do exactly that...
    > http://objectstyle.org/cayenne/api/cayenne/org/objectstyle/cayenne/
    > access/types/package-summary.html. There are some limitations related to
    > the use of inheritance
    > (http://objectstyle.org/jira/secure/ViewIssue.jspa?key=CAY-207), and also
    > use of data rows, but normal object queries and relationships should work
    > just fine.
    >

    Ahh - looks very promising!

    >
    >> Also, while Im writing an email to the list: I noticed that BigDecimals
    >> with a scale can get their scaled values set when pushing to the
    >> database, but the object does not reflect this. For example, if I have a
    >> scale of 2 for a BigDecimal and I set the attribute to "0.155" then
    >> "0.15" is persisted, but the object still states "0.155". DB2 throws an
    >> exception if the scale is wrong, so this behaviour stops the exception
    >> happening (which I tend to agree with from a practical point of view),
    >> but I want the object and database data to match after saving. I had
    >> thought of changing the java template so that BigDecimals are checked
    >> for scale in the set method. Is there a better alternative? Could this
    >> be thought of as a bug, and I need to raise a Jira issue?
    >
    > What is the precision set for DB column (and DbAttribute in the modeler)?
    > Could it be that it is lost because of the column definition or mapping?
    > If this is not the case, please open a bug report.

    Note to self: stop thinking about our existing data layer! There is no
    exception thrown in Cayenne. It does the right thing with the precision in
    terms of persisting. However, that still leaves me with the object being in
    an inconsistent state after the call to save the changes. I will attach a
    sample map (stripped of all but the object I am dealing with) where the
    precision is 2 for the relevant attribute. The following code produces the
    offending output:

        public void testSQLScalableValues() {
            ...
            PayorRole pr = (PayorRole)element.getPayerRoleArray().get(0);
            System.out.println(pr.getAvailableBalance());

            pr.setAvailableBalance(pr.getAvailableBalance().add(new
    BigDecimal("0.005")));
            System.out.println(pr.getAvailableBalance());

            getDataContext().commitChanges();
            System.out.println(pr.getAvailableBalance());

            getDataContext().invalidateObjects(Collections.singletonList(pr));
            System.out.println(pr.getAvailableBalance());
        }

    The output:

    INFO QueryLogger: --- will run 1 query.
    INFO QueryLogger: --- transaction started.
    INFO QueryLogger: SELECT t0.ACCOUNT_BALANCE, ... FROM PAYERROLE t0 WHERE
    t0.PARTY_ID = ? [bind: 787412]
    INFO QueryLogger: === returned 1 row. - took 10 ms.
    INFO QueryLogger: +++ transaction committed.
    6374.32
    6374.325
    INFO QueryLogger: --- transaction started.
    INFO QueryLogger: --- will run 1 query.
    INFO QueryLogger: UPDATE PAYERROLE SET TIME_STAMP = ?, AVAILABLE_BALANCE =
    ? WHERE PAYER_ROLE_ID = ? AND TIME_STAMP = ?
    INFO QueryLogger: [bind: 1100136703475, 6374.325, 117813003, 1100136664119]
    INFO QueryLogger: === updated 1 row.
    INFO QueryLogger: +++ transaction committed.
    6374.325
    INFO QueryLogger: --- will run 1 query.
    INFO QueryLogger: --- transaction started.
    INFO QueryLogger: SELECT t0.ACCOUNT_BALANCE, ... FROM PAYERROLE t0 WHERE
    t0.PAYER_ROLE_ID = ? [bind: 117813003]
    INFO QueryLogger: === returned 1 row. - took 10 ms.
    INFO QueryLogger: +++ transaction committed.
    6374.32

    If you agree that this is a problem, I will log a Jira issue.

    Thanks

    Derek



    This archive was generated by hypermail 2.0.0 : Wed Nov 10 2004 - 20:44:44 EST