Architecture Domain Model and View Model - spring-boot

I am trying to build application by spring boot and Domain Driven Design. I have a problem about Domain model (match with fields of table DB) and View Model (response API).
Domain Model:
EX:
class Name
#Getter
#NoArgsConstructor
#AllArgsConstructor
class Name {
String value;
}
class Product
#Getter
#NoArgsConstructor
#AllArgsConstructor
class Product{
Name name;
}
ViewModel:
#Data
#NoArgsConstructor
#AllArgsConstructor
class ProductView {
//int prodId;
String prodName;
}
Select data DB by class Product, builder to Response API by class ProductView. When that convert from DomainModel to ViewModel or vice versa, I written static method in ProductView for that.
It will become:
#Data
#NoArgsConstructor
#AllArgsConstructor
class ProductView {
//int prodId;
String prodName;
public static ProductView of(Product prod) {
String productName = prod.getName().getValue();
return new ProductView(productName)
}
}
It works well, but when the data becomes more. I think need that as CommonConvert from DomainModel to ViewModel and vice versa.
I have a solution use Mapstruct library. But Mapstruct only support to convert field same type(String with String, ex). What is the best solution for writting CommonConvert?

My advice: do not query domain models and translate them to view models for reading.
Domain model classes (e.g. aggregates) are used to represent business data and behaviour with the to purpose to adhere to business invariants when creating or changing such business entities.
For building your view models from your persistent data you can - and in my opinion you should - bypass the domain model. You can safely read the data from your database as you need it without going through domain repositories.
This is okay because you can't violate business rules by just reading data. For writing data go through domain repositories and aggregates.
In your case you can of course use view model entities using JPA annotations by designing those classes to exactly fit your viewing requirements. Keep in mind that view models often don't correlate to domain models as they might only need a subset of the data or aggregate data from different aggregates.
Another catch is that if you need to query many objects for viewing can quickly cause performance issues if you query full domain aggregates via repositories. As such aggregates always load all data from it's child entities and value objects as well to allow for performing business logic with all invariants you would end up performing lots of expensive queries which are suited for loading a single aggregate but not many of them at once.
So by querying only what you need for viewing you also address such performance issues.
When following DDD you should usually create or change only one aggregate within a business transaction. So domain models are not suited for query optimization but for keeping the business invariants in tact when writing business data.
View models and corresponding queries are optimized for reading and collecting all data required.

Simply map like this (with mapstruct) :
#Mapping(source = "name.value", target = "prodName")
public abstract ProductView toProductView(Product model);

Related

Spring Data- how to tell spring what entities to retrieve

If i have several entites, lets say :
#Entity
class Book{
String name;
Author author;
}
#Entity
class Author{
String name;
City hometown;
}
#Entity
class City{
String cityName;
}
If i want to retrieve all the books, if i use classic JPA Repository and Spring Data and just do a findAll(), it will get me all the books with all the Authors with all their home towns. I know i can use #JsonIgnore, but i think that only prevents whats being returned, not whats being looked up in the database. And also i have methods that DO want to return both books and authors, so #JsonIgnore -ing does not work for me. Is there anything like this ? To tell Spring Data what to look up and what to return ? Any links or guides or methods i don't know of, would be appreciated.
Spring Data has the concept of 'projections' which allow you to return different representations of the same Entity.
Official Documentation:
Spring Data query methods usually return one or multiple instances of
the aggregate root managed by the repository. However, it might
sometimes be desirable to create projections based on certain
attributes of those types. Spring Data allows modeling dedicated
return types, to more selectively retrieve partial views of the
managed aggregates.
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections
Where a Projection is a 'closed' projection (a projection interface whose accessor methods all match properties of the target aggregate) then the documentation notes that additionally:
Spring Data can optimize the query execution [to select only the relevant fields], because we know about
all the attributes that are needed to back the projection proxy
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections.interfaces.closed
Spring Data also allows for Projections to be specified dynamically at runtime. See further:
https://github.com/spring-projects/spring-data-commons/blob/master/src/main/asciidoc/repository-projections.adoc#dynamic-projections
First mark your relations as LAZY
Then specify what data needs to be fetched on a per-query basis.
See for example:
https://vladmihalcea.com/eager-fetching-is-a-code-smell/

asp.net core Identity user customization

Detail
I am developing web application in asp.net core with Identity. now in my application I have two kind of user. Customer and Partner both have different profile information and login scenario.customer can login from simple signup from web page but partner can signup from different view with different mandatory fields.
Problem
How can I design Schema.
what are the good practices in this case.
What are the drawback.
Code
This is what I have done so far
public class ApplicationUser : IdentityUser
{
public CustomerProfile CustomerProfile { get; set; }
}
Use inheritance:
public class ApplicationUser : IdentityUser {}
public class Customer : ApplicationUser
{
// Customer-specific properties
}
public class Partner : ApplicationUser
{
// Partner-specific properties
}
By default, this will be implemented via STI (single-table inheritance). That means you'll have just your standard AspNetUsers table containing columns for the properties on ApplicationUser and all derived types. A discriminator column will be added to indicate which type was actually saved, which will then be used to instantiate the right type when queried.
For the most part, this works just fine. The one downside is that properties on derived classes must be nullable. The reason is simple: it would be impossible to provide values for Customer columns while saving a Partner and vice versa. However, the properties only need be nullable at the database-level. You can still require that they be set in forms and such via a view model.
The alternative is to use TPT (table-per-type). With this approach, you'll get AspNetUsers, but also Customers and Partners tables as well. However, the tables for the derived types will have columns corresponding only to the properties specific to that type and a foreign key back to AspNetUsers. All common properties are stored there. With this, you can now enforce columns have values at the database-level, but querying users will require a join. To use TPT, you simply add the Table attribute to your class, i.e. [Table("Customers")] and [Table("Partners")], respectively.
The one important thing to keep in mind with using inheritance, though, is that you need to work with the type you actually want to be persisted. If you save an ApplicationUser instance, it will be an ApplicationUser, not a Customer or Partner. In this regard, you need to be careful with using the correct types with things like UserManager which generically reference the user type. Even if you create an instance of Customer, if you save it via an instance of UserManager<ApplicationUser>, it will upcast to ApplicationUser and that is what will be persisted. To create a new Customer, you'll need an instance of UserManager<Customer>. Likewise, for partners.
However, this also works to your benefit, as if you attempt to look up a user from an instance of UserManager<Customer> for example, you will only find them if they are in fact a Customer. In this way, it makes it trivially simple to have separate portals where only one or the other can log in, as you've indicated that you want.

Relational model for java composite pattern

I have classes that follow a composite pattern relationship for which I need to create the relational data model for Oracle database.
The (java) classes are as below -
class AbstractEmployee {
int employeeId;
}
class Employee extends AbstractEmployee {
Date joiningDate;
}
class Supervisor extends AbstractEmployee {
List<AbstractEmployee> directs;
int officeLocationId;
}
Clearly, there are attributes which are shared across all classes and there are other attributes which are specific to each class. What would be the best way to create sql tables for the above scenario?
I can see that there are different ways to handle hierarchy namely - TPC, TPH and TPT as provided on this post - inheritance in databases. However, composite patterns pose additional complexity in being intrinsically recursive structures, and as a result, the select/insert query performance can be drastically impacted by the schema.
If possible, please discuss the pros/cons of your solution in terms of scalability and performance.

how to make a spring jpa/correct repository when having mandatory relationships?

I have the following database which allows users to rent books in a book shop:
The entity class Book needs to have a Category as well as BookDescription when saved.
Those Book class looks like this:
#Entity
#Table(name = "books")
#Inheritance(strategy = InheritanceType.JOINED)
public abstract class Book {
#OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinColumn(name = "book_description_id")
private BookDescription bookDescription;
#ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
private Category category;
//omitted fields, getters, setters & other relations
}
I was checking out Spring Data JPA. It has a signature of
CrudRepository<T, ID extends Serializable>
which means that I will have
CrudRepository<Book, String>
but how will I save a book?
So, generally, the user will submit a form, I will bind a BookUIObject which will contain all the details needed to save a book, pass it to a BookService witch will extract from it 3 objects: Book ( a specific implementation), Category and BookDescription. The question is will the service hook up the book relations and call the general repository.save(Book) or it will call a method like repository.save(Book, Category, BookDescription)?
Also, should I bind directly the data from the user into entity classes, or do like I said, bind to a general BookUIObject and let the service extract from it the entity classes?
Kind regards,
Typically you will have to call BookReporitory.save(book). Book has cascaring Persist for both of the relations, so if you have set the BookDescription and the Category on the book instance you save, they will also be persisted. If you didn't have cascading persist, you would have to save them using their JPARepository (unless they already existed in the Persistence context).
One thing that is important to understand in this example is that if you create a new category object and set it on a book and save the book a new category is created in the DB. So if the UI posts category=sic-fi, you have to check if the category already exists, if it does then you must used the managed category, and set that on the book rather than creating another "sci-fi" category. This is the reason I would not have cascading persist on the Category relation, because I would rather have a constraint violation because a category didn't exist, instead of an new category sci-if when someone miss spelled it in the UI.
I do not recommending binding forms directly to JPA entities, because you always need to fetch entities from JPA, as you have to use the managed versions, so in my experience it is better to have another set of beans for form binding.
Another thing that jumps out if the lack of nullable=false in #JoinColumn. If a book can't exist without being in a Category it is vital that this is communicated to the database, and if you generate tables from the JPA metadata model, this is how it is done. If I could give only one recommendation when working with databases/JPA it is to be overzealous with NOT NULL. It is a 100 time easier to get a constraint violation when you insert, than to get a NullPointerException later and have to check every possible code-path that could end up calling save and checking if the argument could be null.
In addition I would recommend that you set of some time to understand the concept of the EntityManager and the Persistence Context, most of the mistakes/assumptions developers make come back to the persistence context and how the 4 entity states work.

MVC3 - Should I design my Model to be tightly coupled to my View?

In working with MVC I am finding my Views to be rigid in terms of their associated Model definition. Should I design my Models around the needs of my view? I realize I can create a container specifically for my view. Then design a second Model in terms of Entities. But, it appears that I always need this stand-between. I mean, there's even a #model to declare what the View is supposed to be coupled to.
For example, I have a View with two tables. The tables both work off the same Entity, so it doesn't make sense to use that Entity as the Model. Rather, the Model needs to be a wrapper that contains 2 of said entities. Moreover, the entities really need to be converted to string[] in order to avoid data massaging in the View.
Am I just too much of an MVC nublet, or is this how MVC is designed to work? Tight relationship with View-Model.
Use a ViewModel for your views. It's bad practice to associate your View with the Model that comes directly from EF.
public class ProductViewModel
{
public ProductViewModel(List<Product> products, List<Category> categories)
{
this.Products = products;
this.Categories = categories;
}
public List<Product> Products { get; private set; }
public List<Category> Categories { get; private set; }
}
ViewModel Best Practices
ASP.NET MVC View Model Patterns
Typically, and I think a lot of the SO/MVC community would agree that following a View Model-esque pattern is extremely beneficial even in the case you're describing. Wrap your entities in a view model class and bind it in the #model statement at the beginning of the view.
The Microsoft guys have recommended the same, though it's not absolute law.
It seems extremely tedious at times, but unless you're writing your own view engines combined with some super advanced model binding logic, the easier path is typically found to be view models. Add more tediousness with data annotations for validation, etc. But to be honest, if advanced model binding and custom view engines are required, your problem has probably been given too much thought.
I agree, don't pass entity classes straight to models. Use your view models to call service or BL classes which assemble the data entities from the data store. I've found the most flexibility when using 1 view per view model, period. To reiterate, that is a 1:1 ratio between view model classes and views. Even if the views have to be broken down into manageable pieces, use display and editor templates to accomplish what you need. It'll help you out later :)

Resources