JHipster is great. It, however, models all objects as domain entity objects. An enum class, for example, is treated as a domain class. If I want to practice the domain driven design, I need to convert some of entity classes, which are generated by JHipster, to value classes along with other types of changes such as replacing primitive types with domain object data types. Can I still run import-jdl after making such changes? In the other words, whether the changes are maintiable with a JDL?
BTW, there is a good talk on DDD by Edson Yanaga posted on youtube.
An interesting talk about DDD:
Implementing DDD with the Spring Ecosystem by Michael Plöd # Spring I/O 2018
There's a concept coming from the video, that I've found very important:
JPA entities are not domain entities.
JPA entities and repositories are what you use to persist data on the Db. While the Domain is what you use inside the application.
To answer, I think that you can build your domain classes separately, without caring too much about JPA entities. I suppose that's better to have a consolidated JPA layer before to start building the Domain side, if the two are somehow linked (and usually they are)
Please consider that I've just started to study this topic. Would be good to hear other opinions.
It's a pity that, in short, JHipster just does not support Value Objects, which makes it incomplete to design a DDD application by only caring about models.
See
issue1,issue2,another SO question
Related
I'm new to Jhipster and I'm trying to understand how Jhipster entity generator work.
I'm trying create 3 simple class: Person, Professor, Student. I created a first entity (Person) and then I would like to create a second one (Professor) and make it extend to the first one but it's not proposed.
How to make the "professor" extends to "Person"? Am I suppose to do it directly on the code or did I miss something somewhere?
As per the docs https://www.jhipster.tech/jhipster-uml/ inheritance is not yet possible by jhipster entity generator yet.
But you can do it manually once entity generator generates the entities.
See this too.
https://github.com/jhipster/jhipster-uml/issues/96
jhipster generates entities not only as classes (spring beans), but also for everything else in the "jhipster-construct": Spring security, relationships, database layout incl. liquibase database refactoring, services, repositories, DTOs, the frontend components with Angular or React, validation and integration and performance tests for back- and frontend. And all in a "best-practice"-manner, with i18n related stuff etc., including two stages, a development and a production profile (with a database for each stage). Additionally, jhipster provides you with all the configuration to deploy contionuously to e.g. heroku with jenkins controlling your git pushes.
To build abstract (java) classes or (java) interfaces isn't possible this way. That may make sense in some business logic, which is to be implemented after generation or there may be other ways than inheritance (e.g. see services and dtos).
The jhipster-generated construct for backend and frontend - or even for microservices and gateways - shows the paths to stay on.
You can manage a lot of things that persons and professors share with OneToOne- or OneToMany-relationships between them and/or additional entities by thinking of database normalization - at least, I have done it this way :-)
I have the following scenario:
A JAX-RS Webservice that is responsable for the business logic and database interactions.
A webapp that will be used by the end users.
A webapp that will be used by administrators.
My problem is that I want to reuse the entities from the webservice on the other apps, but it is highly wrapped with frameworks like JPA, JAX-RS, CDI, among others... So I am having a hard time to isolate them. What I want is to know the best workaround and why should I use it instead of others.
Maybe DTO is the way to go (with support from some object mapper library like Dozer)
Please take a look at following article for more details: http://zezutom.blogspot.com/2012/02/thoughts-on-data-transfer-objects.html
Write you entity objects as Plain Old Java Objects (POJOs), with proper constructors, setters, etc. Apply the annotations that allow the JPA to persist them and do the object to relational mapping in such a way that, if those annotations were all stripped away you could still create and manipulate those objects fully, using the public methods of the class. It can be helpful if you create the POJO first, then add the annotations afterwards.
As the POJOs stand alone they are not at all part of your repository layer. You can use them without using the JPA at all.
My team decided to try DDD approach in new app we're developing now.
One of the obstacles that we face is our platform - we are forced to use ActiveObjects ORM framework (https://developer.atlassian.com/display/DOCS/Getting+Started+with+Active+Objects).
Given that DDD is huge topic by itself, existence of such a constraint makes things more complex. The main problem is propagation of changes of Domain Model entity attributes to the persistence storage via ActiveObjects. Are there any good solutions we can consider?
ORM is a persistence detail i.e totally unrelated to the Domain (different layers). DDD is not a huge topic. It's a simple mindset, tricky to understand and very skill dependent to implement (it's not a "how to" methodology).
DDD uses Repositories for everything persistence related. The Domain only sees the repositories (abstractions only), never the db, orm etc. The ORM is used by the repository. A properly encapsulated domain object might not be easily mappable to an ORM and you'll need different approaches for those cases (the memento pattern is a clean but expensive - boring - to maintain solution). But the essence is that Domain doesn't know about ORM and the Repository is responsible for persisting/retrieving domain objects (using the ORM).
You should also employ CQRS, you don't want your business objects designed for UI or reporting queries.
In a complete Java EE application that's clustered is the DTO pattern still a valid option? The application in question uses EJBs Hibernate and Struts with Spring etc. Is there anything wrong with transferring domain objects in such a scenario?
EDIT: Just to clarify my question, with modern day resources and improvements in Java EE is there a reason not to just use domain objects? If there is not then isn't DTO pattern sort of fading out and shouldn't be used in new applications?
Is not deprecated. It depends on the application architecture if the DTO pattern should be used or not. For example, when you develop Web Services (using JAX-WS or JAX-RS), you should send DTO's over your web methods so a C# or Python client application may consume it, and your web method should not return an object which class has Hibernate annotations, remember than in other languages the Entity won´t be created with those annotations or other business logic inside.
EDIT (Based in your comment): That depends on the software architecture. For example, I'm working on a SOA project and we use DTO's for the Services Layer and the Presentation Layer. More deeper inside, we even use DTO's to handle database communication inside the services, we use only SP's to communicate with DB, so no Hibernate or any other ORM tools can work there, we could use Spring DAO and that framework uses DTO's too. You can find lots of DTO pattern in many applications nowadays.
More info that would be great for this question:
Difference between DTO, VO, POJO, JavaBeans? (where basically, any DTO is a POJO).
Core J2EE Patterns - Transfer Object
EDIT 2: Another source of information that will explain the main reason for using DTO's design, explained by Martin Fowler
LocalDTO
Conclusion: DTO's are not an anti pattern. DTO's are meant to be used only when you need to pass data from one subsystem to another and they don't have a default or standar way to communicate.
It is a very useful pattern in Java EE.
I use a DTO to transfer related entity objects from EJB beans to the UI layer. The entity objects are fetched from DB in one transaction (see TransactionAttributeType.REQUIRED) and stored in the DTO object. The DTO is consumed in the UI layer.
A pattern is pure design. There is no "deprecation" of pattern, but less usage over time (or over-usage).
Personally, I don't see why not to use DTOs.
For example - at oVirt open source project we have entities representing business logic entities in the domain of Virtualization.
These entities should be either annotated by Hibernate annotations (actually, they are today, as we started working on hibernate POCs) and serve as the DTOs , and then have clean from annotations objects that will mapped to them (let's say, using dozer framework) and used by client
(I don't like have at client side code with unnecessary annotations), or the entities should serve as the client objects (value objects) passed to the client and we should have other classes serve as the DTO entities
The minus in the above approach is that you might have 2 parallel class diagrams - one for DTOs and one for value objects (that are used by clients) - but , in many cases in design , there is a trade-off.
You must understand the advantages and disadvantages and pick what is best for you (In our case, since the client side is GWT, it will be easier for us to go for separation to two class hierarchies, one that is DTO/server side and can be also annotated with more server side only annotations, and the other sent to the GWT client code).
I've been doing some reading lately and one thing that I've come across was this article about the Anaemic Domain Model from Martin Fowler. I know, it's old, but somehow very actual in Java world. So I'm trying to move towards a more domain-driven design. One option would be to go with the Active Record model. However, I don't really like the current implementation it has in Scala. It completely couples the domain objects with the persistence type (not so bad in most cases but I have a project where I need to store something both in a RDB and in Mongo). Then I ran across this article about Spring, Hibernate and Scala and though here too the domain object is coupled with the JPA trait, I noticed how he uses Spring to inject a Notification Service. Can't the same mechanism be used to inject a transparent DAO interface? Have you seen this used anywhere? Any thoughts on the idea?
You should have a look at Spring-Data, this project provides some kind of abstraction over different data storages.