How to update a field which is part of primary keys in Moqui? - moqui

Many entities in moqui have primary key of combination of several fields. In some scenarios people may want to update one of field in primary keys. e.g. for product images that is store in ProductContent entity which has primary keys of productId, productContentTypeEnumId, contentLocation, fromDate, people may want to update one image from detail to large, I have not found how to do it in moqui, actually in the entity engine yet.
One solution is to delete it, then add new one. but this sounds weird.

Just to clarify some project structure: The ProductContent entity is actually part of the Mantle Business Artifacts project, and not Moqui Framework. Mantle Business Artifacts is a core part of the Moqui Ecosystem.
For entities with multiple primary key fields this is a database constraint, i.e. you can't update a PK field. You must create a new record, and what you do with the other record is up to the needs of your application (expire, delete, leave, etc).
Something could possibly be added to the Entity Facade to do something like this automatically, but it would be complex. To identify the record the code would have to know the old and new values of the PK field, and what to do with the old record.
Unless a clear pattern emerges for a common use case (and in 14 years of ERP work I can't think of one I've run into very much, though the expire pattern is the most common, such as for the immutable ContactMech records, etc, etc), this is best done by explicit service code and not more automagically though a tool.
If there is a specific pattern you would like to see an extension to the Entity Facade to make it easier, a discussion on the LinkedIn Group would be a good place to initiate that (as opposed to StackOverflow which is for questions and not meant for discussions).

Related

Embeddable vs one to many

I have seen an article in Dzone regarding Post and Post Details (two different entities) and the relations between them. There the post and its details are in different tables. But as I see it, Post Detail is an embeddable part because it cannot be used without the "parent" Post. So what is the logic to separate it in another table?
Please give me a more clear explanation when to use which one?
Embeddable classes represent the state of their parent classes. So to take your example, a StackOverflow POST has an ID which is invariant and used in an unbreakable URL for sharing e.g. http://stackoverflow.com/q/44017535/146325. There are a series of other attributes (state, votes, etc) which are scalar properties. When the post gets edited we have various versions of the text (which are kept and visible to people with sufficient rep). Those are your POST DETAILS.
"what is the logic to separate it in another table?"
Because keeping different things in separate tables is what relational databases do. The standard way of representing this data model is a parent table POST and child table POST_DETAIL with a defined relationship enforced through a foreign key.
Embeddable is a concept from object-oriented programming. Oracle does support object-relational constructs in the database. So it would be possible to define a POST_DETAIL Type and create a POST Table which has a column declared as a nested table of that Type. However, that would be a bad design for two reasons:
The SQL for working with nested tables is clunky. For instance, to get the POST and the latest version of its text would require unnesting the collection of details every time we need to display it. Computationally not much different from joining to a child table and filtering on latest version flag, but harder to optimise.
Children can have children themselves. In the case of Posts, Tags are details because they can vary due to editing. But if you embed TAG in POST_DETAIL embedded in POST how easy would it be to find all the Posts with an [oracle] tag?
This is the difference between Object-Oriented design and relational design.
OO is strongly hierarchical: everything is belongs to something and the way to get the detail is through the parent. This approach works well when dealing with single instances of things, and so is appropriate for UI design.
Relational prioritises commonality: everything of the same type is grouped together with links to other things. This approach is suited for dealing with sets of things, and so is appropriate for data management tasks (do you want to find all the employees who work in BERLIN or whose job is ENGINEER or who are managed by ELLIOTT?)
"give me a more clear explanation when to use which one"
Always store the data relationally in separate tables. Build APIs using OO patterns when it makes sense to do so.

In a DDD architecture, where does a unique ID generation belong to?

Let's say I have a "Project" entity in my domain, that has a to have a unique ID generated (on top of the normal numeric ID) that is 2 letters + 4 digits for every Project. This id has to be unique among all the Projects.
I am having a difficult time placing this functionality, it feels like It should almost only just be placed in the repository when the Project is being saved the first time.
I am sure it doesn't belong to Application services, I am not sure if it is any of the business layers concern to be a domain service, and it feels weird to put it as infrastructure service, but it does need to check if any other Projects exist with a randomly generated [LL]-[DDDD] like code or not.
Even if I place this code around the repository.save it still has to call something from somewhere, so the question is, where should I put a service that gives me a free random Id like that?
Ids which are part of the domain should be generated by the domain.
If the domain do not define any ids you should not expose them in the domain either (strictly speaking, but it's probably easier to include them either way).
Your question mentions a 'normal ID'. I'm assuming that this is your DB's primary key and that the ID you want to generate here is for humans (although why humans would use a 2-letter+4-digit identifier is beyond me, but I've seen worse). In this case, the generation of the key is a business function and ensuring it is unique is a business rule. Both of these things are properly the responsibility of the domain objects. Given your object name, Project, and the language you use in your question, I'd suggest that maybe the Projects object should provide this service. The reason for this is that only the Projects object would have a view over all project objects you've created to check for uniqueness.
Of course, you could have an algorithm to generate this field that ensures uniqueness without having to check all projects (a good idea, btw). In which case you'd probably allow a project to generate its own ID at an appropriate time in its lifecycle (probably when it is created).
The "free random id" or ID generation is part of the infrastructure rather than the business domain so I would add that logic to a persistence layer and call that from within my repositories. e.g ProjectRepository. Assume that the Project entity would have an 'id' field in any case. You can enforce validation in the Project entity so that the id format is 2 letters and 4 digits but only do that if Project ids are different to other entity ids in your application
The first question you need to ask yourself is - why is this constraint on Project ID necessary? Does the user need to know about Project IDs?
If it's informative to the user or if you are implying a form of catalogue of projects, this is a business rule that belongs to the domain. It might require updating your domain model, and therefore refactoring your code in accordance with the new model. Actual id generation will be done by the infrastructure layer, as a new Project is added to the system, but it will use a STRATEGY that expresses the business rule and is defined in the domain layer.
If it's merely a technological requirement, but has no semantic meaning in the domain, either remove the constraint, or place it in the infrastructure layer.
In any case, the infrastructure layer can provide an infrastructure service for id generation of new project entities, which the class responsible for Project entity creation may use (for example, a Project Factory). Project Factories belong to the domain layer, even though they may use an infrastructure service.
Unique identifier generation would normally be an application concern -- these identifiers are analogous to random numbers, or time. They are an input to the deterministic parts of the system.
If you don't consider time an input value, think about it until you do - it is an important concept -- John Carmack, 1998
Ensuring that an identifier (however it was generated) satisfies some uniqueness constraint would be a domain concern, and falls into the general category of set validation.
Note Greg Young's observation:
What is the business impact of having a failure?
If the cost of a failure is small, if failures are easily detected and remedied, then it may be most practical to lean into a "best effort" design. UUID's aren't unique (finite number of bits, we're going to use them all up eventually), but at the scales we are working at the probability of collision is really small. So often, we can just live with it.
But when the impact of a failure is high....
Ensuring that some policy applies to the entire set requires being able to lock the entire set against concurrent modification.
In the easy case - each unique identifier has its own set. One way of framing how repositories work is that they give you the set of all aggregates that match the provided key, and your domain logic is responsibly for ensuring that set has at most one element in it.
In harder cases, the set itself becomes an aggregate, with its own lock, and the domain logic ensures that the each change maintains the invariant of the set. Often, this requires doing a deep analysis of the model to understand which information is actually under the authority of the set, rather than under the authority of other aggregates.

Showing table hierarchy through table names

I am working on redesigning a database for a product called Project Billing. I am having trouble coming up with table names. In the old database, the names were super obscure (PRB_PROJ_LVL), so old is of no help. The database is small - 10 tables or so - but will grow over time.
Here's the problem - Projects are an entity (and table), but the word is also used as an adjetive. Example
Project - a table containing projects.
ProjectTask - a table containing project tasks; this is a child of Projects.
ProjectTemplate - a table for project templates, which is not a child of Projects. Project templates just serve as a model for creating a bunch of ProjectTasks.
So, how do I show that ProjectTask is a child of Project but ProjectTemplate isn't? Thanks as always.
Internal documentation of your schema and its intended use is one of the better ways to do this. Relying on naming convention alone will always leave open the possibility for interpretation - explicit definitions don't do that. That said, we have defined some objects which are intended for use as models (templates in your case). These model objects are not to be used or directly manipulated by the production application and over time are mutable with new objects being based on modified models. One way we tried to apply self-descriptiveness was the introduction of schema. Since we had different departments that could make use of the same model objects, we had something along the lines of (adjusted to apply to your question without assuming too much):
[dept_X].[projects]
[dept_X].[project_tasks]
And for templates, which are never directly used by the application or users (per say):
[model].[projects]
[model].[project_tasks]
As a programming reference for our developers, schema definition scripts contain documentation describing object relationships (as do the objects internally do via foreign keys, etc). As an added measure, a wiki article is generated for all new objects sorted by project. Objects existing prior to this new system (my onboarding) get documented as they get modified or as time permits which ever comes first.

Store files and comments for a web application. Table design

I have a web appliaction with several entities (tables).Each one has his CRUD pages.
I'd like to add for some the, the ability to add comments and attach files.
I was thinking of two scenarios.
One table for all comments/files - table would have some id for the entity and the particular record.
For each entity a separate comments/files table.
The files would be stored on the disk in a directory.In the table would be the name of the file and some additional info.
In term of application Design having one unique table for all coments seems to make sense. In term of application code that mean the same SQL will be reused for all entities. It's the 'classical way' used by most applications, extending on having the same acitive records and controllers used to handle comments and attachments for all objects.
In term of SQL thesecond solution could be usefull in some databases like MySQL to get more Memory Cache benefit. Every comment/attachmlent added in the 1st solution would drop from the memory cache all requests impacting the comment table. With individual tables a comment on one entity would not invalidate queries on other entities. But you would alos require more file descriptors and a bigger table cache.... so to choose this solution you would need a decision based on real-life, precise, case, where you would be able to compare the benefits in database access speed. And when you will add new entities you'll certainly find your each-entity-have-a-comment-table solution boring, things could have been automated by using 1st solution.
It's a tradeoff. With a single comments table, you get a simple, DRY (don't repeat yourself) schema, but you don't get foreign key constraints and thus no cascade deletion. Thus, if you delete an entity with comments, you must also remember to delete the comments!
If you go with multiple comment tables, you get FK constraints and cascade deletion, but you have a "wet" schema (you are repeating yourself). For example, each comment table might have a commentbody column. If you change that column definition, you have to change it in every comment table!
One interesting solution for a DRY-er schema could involve table inheritance (see http://www.postgresql.org/docs/9.0/interactive/ddl-inherit.html) but please read section 5.8.1. Caveats, as there are some "gotchas" regarding indexing, at least in postgres.
Either way, kudos to you for thinking carefully about your database design!

Is retrofitting Entity Framework into my app appropriate for my situation?

So, I have an app that uses a SQL Server express db. I have about 80ish tables all with a primary key but no foreign keys. (The reason we have no foreign keys is because of how we do our sql client-to-server replication. It's not true replication but it's a sync system that was in place when we took over the app. We have no guarantee what records are going to make it to the database first when a client syncs to the server so it is possible that a record would make it to the database with a foreign key that points to a nonexistant record).
We use a type-per-model convention. For each of our business objects there is a table in the db. We currently use stored procedures for every database transaction. This means for every new class there is at least 4 new stored procedures (crud). We have abstracted out our data access layer from our business objects. Each business object has a corresponding businessObjectDAO.
My question is, is entity framework feasible for me to move to? With no foreign key relationships I'm going to have to set up every association between tables manually. Is it worth the time to do this?
My biggest hang up right now is trying to figure out how I map my DAOs to the EF partial classes.
Should I be creating one big .edmx or multiple?
A lot of questions I know. This is my first big architectural type decision and I've been given the go ahead to make the change if I think it is beneficial and feasible.
Maybe I should try Linq-to-SQL? NHibernate is out because we're not allowed using open source products in production (stupid, I know).
Thanks
Cody
My personal recommendation is that if something is working, leave it. I am a big big fan of both LINQ-SQL and Entity Framework, and have managed to get my workplace to make use of the Linq-Sql. I realise that if you did bring one of these in place with your project, maintainability would probably be easier, but by the sounds of it the initial work will be more work than is worth it in the end.