Jhipster : How to generate code for list of Entity / Plural Entity - jhipster

Let's say I have an entity Book
I want Jhipster to generate a Books Entity something like
class Books{
List<Book> books;
}
And Generate corresponding rest controllers like
Books saveAllBooks(Books books)
Books updateAllBooks(Books books)

There's no need to create a Books entity if it contains only a list of Book entities, you could just add manually the list methods to generated REST controllerBookResource.java as you don't need any additional repository.
But if Books has other fields that you want to persist in database, you could generate 2 entities with one-to-many relationship. I wouldn't recommend using plural as it could probably conflict with other generated code.
entity Book{
title String required
}
entity BookBatch{
name String required
}
// RELATIONSHIPS:
relationship ManyToOne {
Book to BookBatch
}

Related

Aggregate or entity without business attributes

Regarding below excerpt, concerning cqrs and ddd, from Patterns, Principles, and Practices of Domain-Driven Design by Nick Tune, Scott Millett
Does it mean that domain model on command side can omit most of business attributes ?
How would it look like for eg Customer Entity?
Could Customer entity omit FirstName, Surname etc?
If so, where would these business attributes be? Only in read model in CustomerEntity?
Or maybe apart from CustomerEntity containing all business attributes there would also be CustomerAggregate wrapping CustomerEntity with 1:1 relation, and command object would operate on CustomerAggregate? (seems strange to me).
What does it mean "Customer entity desn't make sense"?
The text you pointed means that you do not have to model a reusable Entity for your whole system or even for your whole bounded context (Do not model reusable real life things). Doing this is a bad design.
You have to model an Aggregate that performs an action. You feed the Aggregate with only, and just only, the data needed to perform that action and the aggregate response, the changes the domain suffered, is what you have to persist.
Why Entities and V.O.'s then?
To model consistency, encapsulation and decoupling is the basic part but these are implementation details. For DDD what matters is that are different roles (or concepts).
When feeding the aggregate (constructor, function call parameters, etc) the aggregate has to know if it is working with entities and/or with V.O. to build its response.
If the domain action means a change in an attribute of a entity (something with unique identification in your whole system) the response of the aggregate (once all rules and invariants has been checked) should include the new attribute value and the identification of that entity that allows persist the changes.
So, by default, every aggregate has its own entity with the unique identification and the attributes needed for the aggregate action.
One aggregate could have a Customer entity with ID and its Name.
Another aggregate could have a Customer entity with ID and its Karma points.
So every aggregate has its own inner Customer entity to work with. When you feed an aggregate you pass Customer data (i.e. ID and name or ID and Karma points) and the aggregate treats that info as a entity (It is a matter of implementation details if there is a struct, class, etc internally to the aggregate to represent the entity).
One important thing: If you just need to deal with entities ID's then treat it as a V.O. (CustomerIdentityVO) because the ID is immutable and, probably, in that action you just need to write this CustomerIdentityVO in some field in persistence, not change any Customer attribute.
This is the standard vision. Once you start to identify common structures relevant to several aggregates or one aggregate that can perform several actions with the same data fed you start to refactoring, reusing, etc. It just a matter of good OOP design and SOLID principles.
Please, note that I am trying to be higly above of implementation details. I know that you almost always will have unwanted artifacts that depends of programing paradigm type, chosen programing language, etc. but this approach helps a lot avoiding the worse artifact you could have.
Recommended readings:
http://blog.sapiensworks.com/post/2016/07/29/DDD-Entities-Value-Objects-Explained
http://blog.sapiensworks.com/post/2016/07/14/DDD-Aggregate-Decoded-1
http://blog.sapiensworks.com/post/2016/07/14/DDD-Aggregate-Decoded-2
https://blog.sapiensworks.com/post/2016/07/14/DDD-Aggregate-Decoded-3
and
https://blog.sapiensworks.com/post/2016/08/19/DDD-Application-Services-Explained
for a complete puzzle vision.
If you are using Event Sourcing then it's true that you can model aggregates without adding attributes that they don't need for implementing the business logic.
Here's an example:
class Customer {
public Guid ID { get; private set; }
public Customer(Guid id, firstName, lastName, ...) {
ID = id;
this.AddEvent(new CustomerCreatedEvent(id, firstName, ....);
}
public void ChangeName(firstName, lastName) {
this.AddEvent(new CustomerRenamedEvent(this.ID, firstName, lastName),
}
}
Custom only has ID attribute because it needs it to add it to every event that it generates. FirstName and LastName are omitted as they are not needed even when ChangeName method is called. It only records an event that this happened. If your logic requires the FirstName then you can add it. You can omit any properties that you don't need.
Your Repository in this case will save only the events and won't care about the values of the attributes of the Customer.
On the Read side you will probably need these properties as you will display them to your users.
If your aggregates are not event sourced, then you probably will need more attributes on your aggregate to implement it's logic and they will be saved to the database.
Here's an example:
class Customer {
public Guid ID { get; private set; }
public string FirstName { get; private set; }
public string LastName { get; private set; }
public void ChangeName(firstName, lastName) {
FirstName = firstName;
LastName = lastName;
}
}
In this case your Repository will need these properties as it will generate a query to update the database with the new values.
Not sure what "Customer entity doesn't make sense" means.

How can you create a multiple enum using jhipster-jdl?

Let say that we have the following entities and the enum of languages:
entity Resources{
title String required,
text Language,
audio Language
}
enum Language{
SPANISH, ENGLISH, FRENCH, GERMAN
}
And we would like that the audio is a dropdown list where you can choose only one, but the text could be a list where you can choose more than one.
How can you tell Jhypster-JDL that you want to use an array of Languages?
It only lets you choose one... should it be done in the code once it is created?
Thanks
PD: I thought about that, but the problem with creating a language entity and define audio as a one-to-one relationship while text would be a one-to-many relationship like this is that the name variable gets repeated and crashes:
entity Resource{
title String required
}
entity Language{
languages Languages
}
enum Languages{
SPANISH, ENGLISH, FRENCH, GERMAN
}
// RELATIONSHIPS:
relationship ManyToOne {
Language{resource(closedcaption)} to Resource
}
relationship OneToOne {
Resource{language} to Language{resource(video)}
}
// Set pagination options
paginate Resource with pagination
// Set service options to all except few
service all with serviceImpl
#ManyToOne
private Resource resource; <---
#OneToOne(mappedBy = "language")
#JsonIgnore
private Resource resource; <---
So, I might be making a mistake, but I would like to know if besides this solution, is there a way to have an array of something defined in JDL? Let's say an array of Strings?
Thanks again, you are really helpful!
You could define Language as an entity and define audio as a one-to-one relationship while text would be a one-to-many relationship.

In JHipster how to create entity with relationship with User?

I need to create my own entities using the JHipster using the command "yo jhipster:entity myEntity" that have many-to-one relationship with the User entity that comes by default in JHipster.
I have tried unsuccessfully to create in the wizard a relationship with the entity "user" and the field "login" but it is not working.
What is the good way to do this with JHipster? Or do I have to create the entity without JHipster tool (but I need the CRUD!).
Thanks,
Yann
Just an update - jhipster 2.5.0 was released a few days ago adding support for this. Created this answer since the formatting in comments make i pretty hard to read.
When creating a relation for your entity simply answer the questions like this
? Do you want to add a relationship to another entity? Yes
? What is the name of the other entity? user
? What is the name of the relationship? owner
? What is the type of the relationship? many-to-one
? When you display this relationship with AngularJS, which field from 'user' do you want to use? login
Possible values on how to display the relation could be: id, login, first_name, last_name, email
See https://jhipster.github.io/2015/03/01/jhipster-release-2.5.0.html for moreinformation
Just to add to the correct answer by #stoffer, if you're using the jdl it will look like:
relationship ManyToOne {
Owner{user(email)} to User{owner(name)}
}
at a good sample in an official document is say :
entity Blog {
name String required minlength(3),
handle String required minlength(2)
}
relationship ManyToOne {
Blog{user(login)} to User
}
jdl-samples/blog.jh
If you are using the 1.x version, this wasn't made to work, so basically you should do it by hand, without the generator (but it is definitely doable).
For the 2.x version, we have refactored the User object to have an ID field -> this should make this a lot easier, but as this is not released yet, we don't have a feedback at the moment.
I have come into this issue and solved it by using a simple one-to-one relationship first that will extend the user entity, because it is simple and manageable easily and can make the extended entity be the owner of the relationship, then you can create the many-to-one relationship with your entity, like this example:
entity MyEntity {
MyField Type
...
}
entity ApplicationUser {
additionalField Type
...
}
relationship OneToOne {
ApplicationUser{internalUser} to User
}
relationship ManyToOne {
MyEntity{appUser} to ApplicationUser{myEntities}
}
For more details and approach refer to this jHipster page.

Repository transition from DDD to CQRS

Initially my DDD repositories looked like this example:
class PersonRepository {
Person findByID(id)
List<Entity> findAll()
List<Entity> findWithRegex(String)
}
Internally a Service provided the GUI transforming the Entity objects into DTO objects
Now I am trying to get into CQRS. After looking other examples, it seems that my repo should be like this:
class PersonReadModel {
Person findByID(id)
List<DTO> findAll()
List<Entity> findWithRegex(String)
}
With just DDD my repos returned only Entity and List objects. With CQRS since many reads are used only for the UI, there are many read operations that return straight DTOs, therefore PersonReadModel looks like something not quite the traditional DDD repo.
Is this assumption right? Should I have PersonReadModel to return only List and preserve PersonRepository returning Entity and List objects? Should PersonReadModel be a Service that contains a link to the internal repository of a root aggregate?
I can relate a DTO with its Entity since both of them have an identity field. However I am concerned about the displayed DTO being of different revision than the Entity present in my domain model. All CQRS examples I have seen have DTO and Entities with an identity field, but not a revision.
Is the revision something I should be concerned about?
My guess is that the GUI code in the Application Layer will build a message with a DTO and a revision and that the Domain Layer will use to make sure that the requested command was built with the latest version.
ReadModel is on the query side. You don't have to build this part in a DDD way, build it in an easily-query way. Once in a project, I even use public fields read model since they're just data holders.
#Entity
#Table(name="t_order_detail")
public class OrderDetailReadModel {
#Id
public String tracking_id;
public String booking_contact_name;
//other fields
}
public class OrderDetailReadModelQueryObject {
OrderDetailReadModel findBy(String id);
List<OrderDetailReadModel> findByReg(string regex);
}
On the command side, aggregate repository is simplified, most of the time just findById() and store() is needed:
class PersonRepository {
Person findByID(id)
void store(Person person);
}

Multiple similar entities or use the same one in core data?

So I've got a Client entity that needs a relationship to a PhoneNumber entity to allow multiple phone numbers. And I've got an Employee entity that also needs a relationship to a PhoneNumber entity to allow multiple phone numbers. Should I create two separate PhoneNumber entities or can I somehow use the same entity for both?
I would create a parent entity called Person for your Client and Employee entities. The Person entity would have a relationship to the PhoneNumber entity.
Inherited entities have the same attributes and relationships as their parent entity. Of course you can add attributes and relationships to the "child"-entities as well. I omitted that in the screenshot.
Something like this:
you can configure the parent entity in the core data inspector in the right side pane.

Resources