1

Question in short: How can you map/calculate a derived field using JDO/DataNucleus?

Example

An Order can have one or more Items. The field totalItemAmount is the sum of all Items and their amounts. totalItemAmount should not exist as a field in the datastore, but should be calculated.

class diagram of Order and Item

With Hibernate one could use @Formula to annotate totalItemAmount- see https://stackoverflow.com/a/2986354/2294031 .

Is there an equivalent for JDO/DataNucleus?

Workarounds

Because I have not found anything yet, I considered using alternative approaches. But I am not sure which one would be appropriate.

  1. Implementing totalItemAmount as a method: The total amount of items could be calculated with a method (eg. Order.getTotalItemAmount()). The method iterates over all Items of the Order and sums up the amount of each Item. But I imagine this approach would be very slow if I want to display an overview of many orders. Because each time getTotalItemAmount() gets called, all Items of the Order will be (unnecessarily) fetched.
  2. Defining a custom query: Is it possible to define a custom query, which will be used, when DataNucleus obtains Orders from the datastore?
  3. Treating totalItemAmount as a "normal" column (like number): totalItemAmount will be an integer column and everytime the list of Items from the Order gets updated, the totalItemAmount will be updated also. But I do not like this approach, because it could lead to inconsistency - If the order gets modified outside the context (eg. using plain SQL), the content of totalItemAmount could be wrong.
  4. Using a SQL view: I could define a view as described in Hibernate Derived Properties - Performance and Portability. But this would introduce a considerable amount of work and future maintenance - imho too much for the gain.

Is there another way to solve this problem?

Off-Topic: Feel free to comment on my writing, as I really would like to improve it.

Community
  • 1
  • 1
domids
  • 515
  • 5
  • 21
  • 1
    So you need to know when an object is instantiated? ... JDO has lifecycle listeners (and postLoad callback) for that and you can do what you want in your class. – Neil Stockton May 04 '15 at 13:04
  • @NeilStockton Not exactly - I would prefer to use something similar as '@Formula'. Because if I use `postLoad` to calculate `totalItemAmount` all `Items` have be fetched. This would certainly take a lot of time for many `Orders`, wouldn't it? But if this is not possible your input will certainly help with workaround 1 and 3 - thank you. – domids May 04 '15 at 13:23
  • Well PostLoad tells you when an object is loaded, and you can easily fire off a query at that point and assign that field to the result of the query ... same thing as Formula does AFAIK – Neil Stockton May 04 '15 at 13:31
  • @NeilStockton According to http://blog.eyallupu.com/2009/07/hibernate-derived-properties.html `@Formula` works differently - see section "Performance". But I will try it nevertheless. – domids May 04 '15 at 13:41

0 Answers0