should the repository be able to work with entities or just return data? - clean-architecture

Should a repository function return a entity from the database?
For example if I had a entity like this:
class Person(
int id,
string name,
int age
) { ...
and a repository metod, that returns a Person entity like this:
public Person findPersonById(int id)
should this method return the Person entity, so that the repository creates the entity and just returns it, or should the repository return a model with just the data of the PersonEntity and not the entity per se like this:
data class PersonModel(
int id,
string name,
int age
)

A repository object (PersonRepository) is aimed to return a domain entity (Person), by design.
That same repository object probably makes a call to some external resource (person api for example), which returns a model (PersonModel/PersonDTO) to be transformed into domain entity already mentioned. Also, by design.
Later on, presentation layer (or api layer) should probably transform domain entity into a view-model (PersonViewModel) to be returned to client. Again, by design.
Of course, in case your api has few if any business rules, you may want to skip DTOs (PersonModel, PersonViewModel) and work with a(n anemic) domain entity through all layers (infrastructure, application, presentation).
In sum, the repository object "bakes" an entity for the domain (application) layer.

Related

How to fetch multiple entities by a list of natural ids with Hiberate or JPA repository?

If I have a list of natural Ids, how can I fetch all the records in the DB associated with these natural Ids at once?
All I've seen are methods that let you find an entity by a natural Id, an example of one is shown below.
#Override
public Optional<T> findBySimpleNaturalId(ID naturalId) {
Optional<T> entity = entityManager.unwrap(Session.class)
.bySimpleNaturalId(this.getDomainClass())
.loadOptional(naturalId);
return entity;
}
I am looking for a method that can take a list natural Ids and fetch all the entities with these natural Ids. My current Entity has a autogenerated UUID and a naturalId and I'd like to keep it this way.
Is there something like this below
List<Song> songs = entityManager
.unwrap(Session.class)
.byMultipleSimpleNaturalIds(Song.class)
.multiLoad(songGroup.getSongIds());
// or using the repository
customRepository.findAllByNaturalId(...)
The examples you've seen are showing you how to build them yourself, as spring does not provide individual methods for you; it knows nothing about properties in your entity other than it must have an id. If you want a findAllByNaturalId method, you have to define it in the interface.
Specifying this in your customRepository:
public List<Song> findByNaturalIdIn(List<Int> naturalIds);
Spring should generate an implementation that creates a query similar to "Select s from Song s where s.naturalId In :naturalIds".
If it doesn't, just add that JPQL query string as an annotation and it will execute it for you:
#Query(value = "Select s from Song s where s.naturalId In :naturalIds")
public List<Song> findByNaturalIdIn(List<Int> naturalIds);
Or you can write your own implementation method to execute your loadOptional calls, or any query you wish, but you still must define the method in your repository.

Is double saving a new entity instance with a Spring data 2 JpaRepository correct?

I have two entities in a bi-directional many to many relationship.
A <-> many to many <-> B
I have an endpoint where a client can create an instance of A, and at the same time add some number of B entities to that A, by passing in an array of B entity id keys. Please keep in mind that these B entities already exist in the database. There is no business or software design case for tightly coupling their creation to the creation of A.
So class A looks like this, and B is the same, but with references to A.
#Entity
class A {
#Id
#GeneratedValue
int id;
#ManyToMany
List<B> bs;
String someValue;
int someValue2;
// With some getters and setters omitted for brevity
}
So at first try my endpoint code looks like this.
public A createA(#RequestBody A aToCreate) {
A savedA = aRepository.save(aToCreate);
savedA.getbs().forEach(b -> Service.callWithBValue(b.getImportantValue());
}
And the client would submit a JSON request like this to create a new A which would contain links to B with id 3, and B with id 4.
{
"bs": [{id:3}, {id:10}],
"someValue": "not important",
"someValue2": 1
}
Okay so everything's working fine, I see all the fields deserializing okay, and then I go to save my new A instance using.
aRepository.save(aToCreate);
And that works great... except for the fact that I need all the data associated with the b entity instances, but the A object returned by aRepository.save() has only populated the autofill fields on A, and done nothing with the B entities. They're still just hollow entities who only have their ids set.
Wut.
So I go looking around, and apparently SimpleJpaRepository does this.
#Transactional
public <S extends T> S save(S entity) {
if (entityInformation.isNew(entity)) {
em.persist(entity);
return entity;
} else {
return em.merge(entity);
}
}
And since the A entity is brand new, it only persists the A entity, but it doesn't merge it so I don't get any of the rich B data. So okay, if I modify my code to take this into account I get this.
public A createA(#RequestBody A aToCreate) {
A savedA = aRepository.save(aRepository.save(aToCreate));
savedA.getbs().forEach(b -> Service.callWithBValue(b.getImportantValue());
}
Which works just fine. The second pass through the repository service it merges instead of persists, so the B relationships get hydrated.
My question is: Is this correct, or is there something else I can do that doesn't look so ineloquent and awful?
To be clear this ONLY matters when creating a brand new instance of A, and once A is in the database, this isn't an issue anymore because the SimpleJpaRepository will flow into the em.merge() line of code. Also I have tried different CascadingType annotations on the relationship but none of them are what I want. Cascading is about persisting the state of the parent entity's view of its children, to its children, but what I want to do is hydrate the child entities on new instance creation, instead of having to make two trips to the database.
In the case of a new A, aToCreate and savedA are the same instance because that is what the JPA spec madates:
https://docs.oracle.com/javaee/6/api/javax/persistence/EntityManager.html#persist(java.lang.Object)
Make an instance managed and persistent.
Spring Data simply returns the same instance so persist/merge can be abstracted into one method.
If the B instances you wish to associate with A are existing entities then you need to fetch a reference to these existing instances and set them on A. You can do this without a database hit by using the T getOne(ID id) method of Spring Data's JpaRepository:
https://docs.spring.io/spring-data/jpa/docs/2.1.4.RELEASE/api/
You can do this in your controller or possibly via a custom deserializer.
This is what I ended up going with. This gives the caller the ability to save and hydrate the instance in one call, and explains what the heck is going on. All my Repository instances now extend this base instance.
public interface BaseRepository<T, ID> extends JpaRepository<T, ID> {
/**
* Saves an instance twice so that it's forced to persist AND then merge. This should only be used for new detached entities that need to be saved, and who also have related entities they want data about hydrated into their object.
*/
#Transactional
default T saveAndHydrate(T save) {
return this.save(this.save(save));
}
}

Web API is it necessary to have ViewModels layer classes?

When I use Web (MVC), I always to create a separate classes layer. These classes often the same as DTO classes, but with attributes like [Display(Name = "Street")] and validation. But for web api Display attributes are not necessary, validation can be used by FluentValidation. Should Api controller returns ViewModels classes or DTO classes will be fine too?
the answer, as always is .... it depends.
If your API is serving multiple clients , apps etc, then returning DTOs is a better options.
ViewModels are specific to the MVC client and should already be prepared for display, meaning the data should already be formatted in a specific way, some fields maybe combined, they should satisfy whatever requirements the display pages have. They are called ViewNodels for a reason. The point is that they are rarely exactly the same as the data the API returns, which should be a bit more generic and follow a certain pattern to make sense to its users.
If your ViewModels are exactly the same and you only have one client then it's up to you if you want to create a set of duplicated classed just to avoid having the attributes.
Mapping from DTO to ViewModel and viceversa is not exactly complicated, but the process does introduce one more complication, one more layer.
Don't forget one thing though. API DTOs are supposed to return the data they have on any entity regardless of the requirements of any UI. Requirements can change anyway, new fields added or discarded. You're more than likely to leave the API alone when that happens and simply change your ViewModels.
Your ViewModels are specific to a UI page and should contain only the data required by that page. This means that you can end up with multiple ViewModels for the same data, it's just that the display requirements are different for each.
My vote goes towards keeping the ViewModels and DTOs separate, even if, at this point in time they are exactly the same. Thins always change and this is one of those things you can actually be ready for.
Actually it depends on application's architecture how we want to return response. In this case yes we can return DTO classes but i think that would not be the good approach because we should create a separate Resource classes that will map with DTO and then return. Just see the below example:
public class CustomerDTO
{
public int ID { get; set; }
public string Name { get; set; }
public int DepartmentId { get; set; }
}
public class CustomerResource
{
[JsonObject]
public string Name { get; set; }
[JsonObject]
public string Department { get; set; }
}
Suppose we have CustomerDTO class and we want to return response in the following json format
{
"name":"Abc xyz",
"department":"Testing"
}
So in this case we should we have separate class that will return as a response to the end user as i created CustomerResource. In this scenario we will create a mapper that will map DTO with resource object.
And also with this implementation we can test resources independently

Rich vs Anemic Domain Model [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I am deciding if I should use a Rich Domain Model over an Anemic Domain Model, and looking for good examples of the two.
I have been building web applications using an Anemic Domain Model, backed by a Service --> Repository --> Storage layer system, using FluentValidation for BL validation, and putting all of my BL in the Service layer.
I have read Eric Evan's DDD book, and he (along with Fowler and others) seems to think Anemic Domain Models are an anti-pattern.
So I was just really wanting to get some insight into this problem.
Also, I am really looking for some good (basic) examples of a Rich Domain Model, and the benefits over the Anemic Domain Model it provides.
The difference is that an anemic model separates logic from data. The logic is often placed in classes named **Service, **Util, **Manager, **Helper and so on. These classes implement the data interpretation logic and therefore take the data model as an argument. E.g.
public BigDecimal calculateTotal(Order order){
...
}
while the rich domain approach inverses this by placing the data interpretation logic into the rich domain model. Thus it puts logic and data together and a rich domain model would look like this:
order.getTotal();
This has a big impact on object consistency. Since the data interpretation logic wraps the data (data can only be accessed through object methods) the methods can react to state changes of other data -> This is what we call behavior.
In an anemic model the data models can not guarantee that they are in a legal state while in a rich domain model they can. A rich domain model applies OO principles like encapsulation, information hiding and bringing data and logic together and therefore a anemic model is an anti pattern from an OO perspective.
For a deeper insight take a look at my blog https://www.link-intersystems.com/blog/2011/10/01/anemic-vs-rich-domain-models/
Bozhidar Bozhanov seems to argue in favor of the anemic model in this blog post.
Here is the summary he presents:
domain objects should not be spring (IoC) managed, they should not have DAOs or anything related to infrastructure injected in them
domain objects have the domain objects they depend on set by hibernate (or the persistence mechanism)
domain objects perform the business logic, as the core idea of DDD is, but this does not include database queries or CRUD – only operations on the internal state of the object
there is rarely need of DTOs – the domain objects are the DTOs themselves in most cases (which saves some boilerplate code)
services perform CRUD operations, send emails, coordinate the domain objects, generate reports based on multiple domain objects, execute queries, etc.
the service (application) layer isn’t that thin, but doesn’t include business rules that are intrinsic to the domain objects
code generation should be avoided. Abstraction, design patterns and DI should be used to overcome the need of code generation, and ultimately – to get rid of code duplication.
UPDATE
I recently read this article where the author advocates of following a sort of hybrid approach - domain objects can answer various questions based solely on their state (which in the case of totally anemic models would probably be done in the service layer)
My point of view is this:
Anemic domain model = database tables mapped to objects (only field values, no real behavior)
Rich domain model = a collection of objects that expose behavior
If you want to create a simple CRUD application, maybe an anemic model with a classic MVC framework is enough. But if you want to implement some kind of logic, anemic model means that you will not do object oriented programming.
*Note that object behavior has nothing to do with persistence. A different layer (Data Mappers, Repositories e.t.c.) is responsible for persisting domain objects.
When I used to write monolithic desktop apps I built rich domain models, used to enjoy building them.
Now I write tiny HTTP microservices, there's as little code as possible, including anemic DTOs.
I think DDD and this anemic argument date from the monolithic desktop or server app era. I remember that era and I would agree that anemic models are odd. I built a big monolithic FX trading app and there was no model, really, it was horrible.
With microservices, the small services with their rich behaviour, are arguably the composable models and aggregates within a domain. So the microservice implementations themselves may not require further DDD. The microservice application may be the domain.
An orders microservice may have very few functions, expressed as RESTful resources or via SOAP or whatever. The orders microservice code may be extremely simple.
A larger more monolithic single (micro)service, especially one that keeps it model in RAM, may benefit from DDD.
First of all, I copy pasted the answer from this article
http://msdn.microsoft.com/en-gb/magazine/dn385704.aspx
Figure 1 shows an Anemic Domain Model, which is basically a schema with getters and setters.
Figure 1 Typical Anemic Domain Model Classes Look Like Database Tables
public class Customer : Person
{
public Customer()
{
Orders = new List<Order>();
}
public ICollection<Order> Orders { get; set; }
public string SalesPersonId { get; set; }
public ShippingAddress ShippingAddress { get; set; }
}
public abstract class Person
{
public int Id { get; set; }
public string Title { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string CompanyName { get; set; }
public string EmailAddress { get; set; }
public string Phone { get; set; }
}
In this richer model, rather than simply exposing properties to be read and written to,
the public surface of Customer is made up of explicit methods.
Figure 2 A Customer Type That’s a Rich Domain Model, Not Simply Properties
public class Customer : Contact
{
public Customer(string firstName, string lastName, string email)
{
FullName = new FullName(firstName, lastName);
EmailAddress = email;
Status = CustomerStatus.Silver;
}
internal Customer()
{
}
public void UseBillingAddressForShippingAddress()
{
ShippingAddress = new Address(
BillingAddress.Street1, BillingAddress.Street2,
BillingAddress.City, BillingAddress.Region,
BillingAddress.Country, BillingAddress.PostalCode);
}
public void CreateNewShippingAddress(string street1, string street2,
string city, string region, string country, string postalCode)
{
ShippingAddress = new Address(
street1,street2,
city,region,
country,postalCode)
}
public void CreateBillingInformation(string street1,string street2,
string city,string region,string country, string postalCode,
string creditcardNumber, string bankName)
{
BillingAddress = new Address (street1,street2, city,region,country,postalCode );
CreditCard = new CustomerCreditCard (bankName, creditcardNumber );
}
public void SetCustomerContactDetails
(string email, string phone, string companyName)
{
EmailAddress = email;
Phone = phone;
CompanyName = companyName;
}
public string SalesPersonId { get; private set; }
public CustomerStatus Status { get; private set; }
public Address ShippingAddress { get; private set; }
public Address BillingAddress { get; private set; }
public CustomerCreditCard CreditCard { get; private set; }
}
One of the benefit of rich domain classes is you can call their behaviour (methods) everytime you have the reference to the object in any layer. Also, you tend to write small and distributed methods that collaborate together. In anemic domain classes, you tend to write fat procedural methods (in service layer) that are usually driven by use case. They are usually less maintainable compared to rich domain classes.
An example of domain classes with behaviours:
class Order {
String number
List<OrderItem> items
ItemList bonus
Delivery delivery
void addItem(Item item) { // add bonus if necessary }
ItemList needToDeliver() { // items + bonus }
void deliver() {
delivery = new Delivery()
delivery.items = needToDeliver()
}
}
Method needToDeliver() will return list of items that need to be delivered including bonus. It can be called inside the class, from another related class, or from another layer. For example, if you pass Order to view, then you can use needToDeliver() of selected Order to display list of items to be confirmed by user before they click on save button to persist the Order.
Responding To Comment
This is how I use the domain class from controller:
def save = {
Order order = new Order()
order.addItem(new Item())
order.addItem(new Item())
repository.create(order)
}
The creation of Order and its LineItem is in one transaction. If one of the LineItem can't be created, no Order will be created.
I tend to have method that represent a single transaction, such as:
def deliver = {
Order order = repository.findOrderByNumber('ORDER-1')
order.deliver()
// save order if necessary
}
Anything inside deliver() will be executed as one single transaction. If I need to execute many unrelated methods in a single transaction, I would create a service class.
To avoid lazy loading exception, I use JPA 2.1 named entity graph. For example, in controller for delivery screen, I can create method to load delivery attribute and ignore bonus, such as repository.findOrderByNumberFetchDelivery(). In bonus screen, I call another method that load bonus attribute and ignore delivery, such as repository.findOrderByNumberFetchBonus(). This requires dicipline since I still can't call deliver() inside bonus screen.
I think the root of the problem is in false dichotomy. How is it possible to extract these 2 models: rich and "anemic" and to contrast them to each other? I think it's possible only if you have a wrong ideas about what is a class. I am not sure, but I think I found it in one of Bozhidar Bozhanov videos in Youtube. A class is not a data + methods over this data. It's totally invalid understanding which leads to the division of classes into two categories: data only, so anemic model and data + methods - so rich model (to be more correct there is a 3rd category: methods only even).
The true is that class is a concept in some ontological model, a word, a definition, a term, an idea, it's a DENOTAT. And this understanding eliminates false dichotomy: you can not have ONLY anemic model or ONLY rich model, because it means that your model is not adequate, it's not relevant to the reality: some concepts have data only, some of them have methods only, some of them are mixed. Because we try to describe, in this case, some categories, objects sets, relations, concepts with classes, and as we know, some concepts are processes only (methods), some of them are set of attributes only (data), some of them are relations with attributes (mixed).
I think an adequate application should include all kinds of classes and to avoid to fanatically self-limited to just one model. No matter, how the logic is representing: with code or with interpretable data objects (like Free Monads), anyway: we should have classes (concepts, denotats) representing processes, logic, relations, attributes, features, data, etc. and not to try to avoid some of them or to reduce all of them to the one kind only.
So, we can extract logic to another class and to leave data in the original one, but it has not sense because some concept can include attributes and relations/processes/methods and a separating of them will duplicate the concept under 2 names which can be reduced to patterns: "OBJECT-Attributes" and "OBJECT-Logic". It's fine in procedural and functional languages because of their limitation but it's excessive self-restraint for a language that allows you to describe all kinds of concepts.
Anemic domain models are important for ORM and easy transfer over networks (the life-blood of all comercial applications) but OO is very important for encapsulation and simplifying the 'transactional/handling' parts of your code.
Therefore what is important is being able to identify and convert from one world to the other.
Name Anemic models something like AnemicUser, or UserDAO etc so developers know there is a better class to use, then have an appropriate constructor for the none Anemic class
User(AnemicUser au)
and adapter method to create the anemic class for transporting/persistence
User::ToAnemicUser()
Aim to use the none Anemic User everywhere outside of transport/persistence
The classical approach to DDD doesn't state to avoid Anemic vs Rich Models at all costs. However, MDA can still apply all DDD concepts (bounded contexts, context maps, value objects, etc.) but use Anemic vs Rich models in all cases. There are many cases where using Domain Services to orchestrate complex Domain Use Cases across a set of domain aggregates as being a much better approach than just aggregates being invoked from application layer. The only difference from the classical DDD approach is where does all validations and business rules reside? There’s a new construct know as model validators. Validators ensure the integrity of the full input model prior to any use case or domain workflow takes place. The aggregate root and children entities are anemic but each can have their own model validators invoked as necessary, by it’s root validator. Validators still adhered to SRP, are easy to maintain and are unit testable.
The reason for this shift is we’re now moving more towards an API first vs an UX first approach to Microservices. REST has played a very important part in this. The traditional API approach (because of SOAP) was initially fixated on a command based API vs. HTTP verbs (POST, PUT, PATCH, GET and DELETE). A command based API fits well with the Rich Model object oriented approach and is still very much valid. However, simple CRUD based APIs, although they can fit within a Rich Model, is much better suited with simple anemic models, validators and Domain Services to orchestrate the rest.
I love DDD in all that it has to offer but there comes a time you need stretch it a bit to fit constantly changing and better approach to architecture.
Here is a example that might help:
Anemic
class Box
{
public int Height { get; set; }
public int Width { get; set; }
}
Non-anemic
class Box
{
public int Height { get; private set; }
public int Width { get; private set; }
public Box(int height, int width)
{
if (height <= 0) {
throw new ArgumentOutOfRangeException(nameof(height));
}
if (width <= 0) {
throw new ArgumentOutOfRangeException(nameof(width));
}
Height = height;
Width = width;
}
public int area()
{
return Height * Width;
}
}

Integration Test Strategy for Create methods

I want to test if created entity has been correctly persisted to database.There is a service integration test for create method:
#SpringApplicationContext({"setting ...."})
public class PersonServiceIntegrationTest extends UnitilsJUnit4 {
#SpringBeanByName
private PersonService personService;
#Test
public void createPerson() {
String name = "Name";
String sname = "Surename";
DtoPerson item = personService.createPerson(name, sname, Arrays.asList( new DtoAddress("Pisek","CZE", true), new DtoAddress("Strakonice", "CZE", false) );
Assert.notNull("Cannot be null", item);
/*
* This assertion fails because of transaction (I suppose) - item is not in
* database right now.
* Why? Returned dto 'item; is not null?
*/
//domain with all fetched related entities, eg. address
Person p = personService.getPerson(item.getIdPerson());
List<Address> addresses = p.getAddresses();
Assert.notNull("Cannot be null", p);
Assert.notNull("Cannot be null", addresses);//return collection of Address
Assert.notFalse("Cannot be emtpty", addresses.isEmpty());
ReflectionAssert.assertPropertyLeniens("City", Arrays.asList("Pisek", "Strakonice"), addresses);
}
}
Is it necessary to test create entity if I use hibernate? Someone can write you try to test low-level hibernate but hibernate has own tests. There is a trivial code above but I can imagine some specific code which persists more entites at same time (eg. one-many plus several one-one relations). And I want to test if relations has been correctly persisted.
Is there a pattern to do test this way? I have a problem, that record is not at database. I don't want to use returned dto (it presents only agregate root entity - person, but it does not say about person basic data (one-many), person address (one-many) etc.)... i want to get persisted record.
What I do to test the persistence is:
1) I create the Domain entity,
2) save it with Hibernate/JPA,
3) flush and clear the hibernate session/entity manager
4) load the entity again with hibernate
5) compare the original entity with the one that I have (re)loaded
so I am pretty sure that the mapping is more or less correct and every thing get persisted
I decided to rework service method for create person.
PersonService is responsible only to create domain entity Person - test will do only test the returned DtoPerson and its values.
PersonService will inject AddressService, PersonBasicDataService, which they have own create methods with collection as parameter. These services will have own test classes and test only returned collection of DtoAddress or DtoPersonBasicData.
Tests will be simply and will solve only own responsibility. :-)
As #Ralph said in comments under his answer - this test case is not about service layer. There is necessary to test domain layer. And what there is a new idea which I do not use in integration tests - tests has own hibernate session.

Resources