I am not if it works, because I haven't tried it yet:
Probably you could use the @javax.persistence.PrePersist and @javax.persistence.PreUpdate Callback Events in your Project Entity Bean for accumulating your expenses and then setting spentAmt.
You could take the suggestion of using persistence events to accumulate a running tally, but I would at most use such a total to update the UI with a "non-authoritative figure". Especially for financial data, you should only have one authoritative definition of any figure, and that should be from the only source that is guaranteed to have all the data, and that's the database. Your app might not be the only thing that ever updates the expenses tables in the future.
You probably don't want to do the sums by fetching all the expense objects though, so you'd be best off with a scalar query, a raw sql query, or best yet, a stored procedure. It's going to be ridiculously fast in almost any database, and lends itself to optimizations like partitioning if you need it.
Thanks for the feedback! Chuck's argument is hard to resist--best accurate data is using the db and using db logic the performance hit shouldn't be terrible.
I've implemented a computed field using a @Formula annotation on the spentAmt's getter and this works great--almost.
One problem: After I add an Expense (expense edit page) I redirect to my Project screen, but I still see the old calculated value for spentAmt. For some reason the new value reflecting my Expense addition isn't rendered. If I manually refresh the screen using the browser then I do get the correctly computed (new) values. Huh?
Any idea why isn't my computed field being refreshed when the page is rendered?
May be you have another instance in the presentation view?
It's possible but I don't think so. My debug page shows one projectHome component in the Application context and no conversations when the Project summary page is loaded.
I also determined that the getters that use the @Formula to compute the total in Project are being called (multiple times) during the screen render, even though the new results aren't appearing on the display.
I could be absolutely dead wrong, but since the getter is actually being called it feels like something in the UI has decided not to render the new result (until a hard-reload), and instead is using a cached value someplace.
I'll amend my last reply. When I'm in my Expense screen adding a new Expense there is a conversation running with a ProjectHome instance in it (presumably containing a Project instance). This context ends when I return to the Project screen.
Perhaps this is the instance being updated not whichever one is in the default context (which definitely does hold a Project instance somewhere)?
The problem remains though--how can I tell Seam I want to refresh/rerender the original Project? (If I nav away from the Project screen then return it renders the correct value--just not immediately after create/edit of an Expense.)