Embedded Values - Modeling Money Objects in DB_VA for PHP

I’ve found another HUGE problem with DB_VA (for PHP) that I would appreciate someone’s help with. I’ll explain it using a simple example:

I have products and each product has a newPrice and oldPrice. Moreover, I want each price to have both an amount and a currency. I’ve modeled this with a Product class and a Money class. The Product class needs to be saved to the database, so it’s stereotyped “ORM persistable”. It makes no sense to me to make the Money class persistent, as I don’t want a database table just full of prices. So, ideally, I want Money objects to be “Embedded Values” (see Fowler “Patterns of Enterprise Application Architecture” p.268) in the CLASS (and table) to which they belong. For example, I want the Product class to have two attributes (“newPrice” and “oldPrice”) which are both of type “Money” class, and then I want the Product table to have 4 columns (newPrice_amount, newPrice_currency, oldPrice_amount, oldPrice_currency).

But here’s the problem:

If I try to specify that the “newPrice” and “oldPrice” attributes are of type “Money”, I get an error when I try to generate the PHP code saying that Money is not a supported type. Apparently, that leaves me with the option of creating two associations between the Product and Money classes, one for “oldPrice” and another for “newPrice”. But this forces me to make the Money class “ORM persistable”, which creates a TABLE of money objects, which is not what I want. I want the values of money objects to be embedded in the products table, while still being able to keep the Money class a separate class. I only want two attributes in the Product class: newPrice and oldPrice. I don’t want to have to define four attributes in the Product class: newPrice_amount, newPrice_currency, oldPrice_amount, oldPrice_currency, though I want these four as table columns in the Product table.

How do I do this in DB_VA for PHP?

Thanks!
E

Hi everbored,

Same as the previous one. This one has been answered by our team already.

Please feel free to post again if there are any other questions.

Best regards,
Jick

Hello, we are in an evalition phase and tryed DB-VA in the last weeks. Today we had the same problem which everbored mentioned in the inital post, but in Java.
Jick you, mentioned the problem was solved before. Where can i find the solution? Can you give me a link to the solution? I tried the forum search but i found nothing.

Hi user,

Normally only presistable class can be used as non-primitive type in the referenced attribute. But according to your requirement, do you think this can help? You can have the old/new price in the Product class and provide methods for retrive the price as Money class. Then create the ProductImpl class and do the actual implementation (see attached image). Do you think this can help?

Best regards,
Jick

Class Diagram1.jpg

Thanx for your proposal., but in our case this solution don’t fit, and from architectural point of view it’s very weak.
If i do as you said i have many work if the complex datatype changes in its structure.
Is there no possibility in DB-VA to define a explicite mapping for complex datatypes.

For example:

Class Product {
Money oldprice;
Money newprice;
}

maps to an entity :
PRODUCT(
DECIMAL oldprice_value,
VARCHAR oldprice_currency,
DECIMAL newprice_value,
VARCHAR newprice_currency

)

Regards
Friedbert

[quote=friedsam72]Is there no possibility in DB-VA to define a explicite mapping for complex datatypes.

For example:

Class Product {
Money oldprice;
Money newprice;
}

maps to an entity :
PRODUCT(
DECIMAL oldprice_value,
VARCHAR oldprice_currency,
DECIMAL newprice_value,
VARCHAR newprice_currency

)[/quote]

Hi Friedbert,

I think that you can use an ORM Component just for that. An ORM Component “behaves” like a Class (in fact, it has code) but it is stored inside the “big brother” class associated table that contains it.

I mean, follow this steps:

  • Create new ORM Persistable class, “Product”
  • Using contextual menu, select “Composition - ORM Component Class”
  • Name the new ORM Component “Money”
  • Rename the association role next to money from “-money” to “-oldprice”
  • Set the opposite association’s role navigable=false
  • Repeat “Composition - ORM Component Class” but in this case point to the already created ORM Component (“Money”)
  • Rename the association role from “-money” to “-newprice”
  • Again, set the opposite association’s role navigable=false
  • Add “value” and “currency” attributes to the money class
  • Sync to ERD to see the resulting entity

The attached image shows the final result. I think this is what you were looking for. If not, let me know :smiley:

Best regards!!

image.png

Hello distansia,
thanx for this solution, it works great.
Best Regards
Friedbert