I do not have bug. I just have situation with various alternative solutions and wanted your opinions on which is best.
The domain layer developer here always makes things complicated for me (I am persistence layer developer and data modeller). This situation no different.
Domain layer guy is building accounting system that can account for money but also for quantities of product (e.g. wheat) moving in and out of inventory. He calls the money case, Financial Accounting and other case Product Accounting. With me so far?
Okay, for Financial Accounting, the accountant can create, delete and edit all the FinancialAccounts as much as he wants. For example, he can create a cash FinancialAccount:
accountId = 100
accountName = Cash
However, for Product Accounting, accounts are all predetermined. ProductAccounts CANNOT be created, deleted or edited in any way by the user. In a sense, ProductAccounts are hard coded. For example, the system knows the ProductAccount with accountId 57 is for tracking of the quantity of product shipped and account 58 is for tracking the quantity of product sold but not yet shipped.
We have a base class, Account, which has common property accountId. ProductAccount extends Account. FinancialAccount extends Account and adds other properties like accountName.
We have other classes like JournalEntryLineItem that reference Account (i.e the base class, not the specific subclasses). For example:
Code:
class JournalEntryLineItem
{
Account account;
int amount;
// ...other properties
}
Because FinancialAccounts can be added, deleted and edited by user, it makes sense for them to be mapped as entities and be stored in a database table.
However, since ProductAccounts are fixed and really only have accountId property, they
could be mapped as values instead of entities. In other words, we have options for how to map ProductAccounts.
If ProductAccounts are mapped as entities and stored in database along with FinancialAccounts, data model is simple and I do NOT need any special UserTypes. This makes my happy. For example, table JOURNAL_ENTRY_LINE_ITEM might look like this:
Code:
JOURNAL_ENTRY_ID (part of PK; also FK referencing JOURNAL_ENTRY table)
LINE_NUMBER (part of PK)
ACCOUNT_ID (FK referencing ACCOUNT table)
AMOUNT
On other hand, treating ProductAccounts as values makes it easier for domain layer guy to use ProductAccounts in his code; he can just create the fixed set of them as constants rather than having to create a Session and load them. This simplifies his code a lot.
However, if ProductAccounts are values and are NOT stored in the database, my data model gets more complicated and I have to create a CompositeUserType to map Account. For example, table JOURNAL_ENTRY_LINE_ITEM might look like this now:
Code:
JOURNAL_ENTRY_ID (part of PK; also FK referencing JOURNAL_ENTRY table)
LINE_NUMBER (part of PK)
FINANCIAL_ACCOUNT_ID (FK referencing FINANCIAL_ACCOUNT table)
PRODUCT_ACCOUNT_ID (NOT a FK because ProductAccounts not in database)
AMOUNT
In this case, FINANCIAL_ACCOUNT_ID is foreign key referencing FINANCIAL_ACCOUNT table. However, PRODUCT_ACCOUNT_ID is NOT a FK because ProductAccounts not in database. Obviously, these two fields would be mutually exclusive and one (but not both) would be required to be non-null. But you say "How do you map this?". Well, I have already created a CompositeUserType that can persist a class whose subclasses can be either entities or values. I was not hard at all. I followed
this ValueAndEntityUserType example and modified it to suit my needs.
So to make long story short, which option would you choose and why?:
1) Map ProductAccount as entity (easier for DBA/persistence layer developer - that's me)
OR
2) Map ProductAccount as value (easier for domain layer developer)