Although I can’t say why the decision was made by the team, I absolutely agree that the concept of DTO / VM is not very clear.
I think the basic idea was similar to the MVP / MVC pattern, where a new view model is often introduced to get the MVVM pattern. Thus, DTOs that do not affect any representation are “pushed” to the actual level of the model / controller. This is normal if you say that the DTO is a passing entity between services.
However, we also had “problems” and a lot of discussions with layers, DTO, VM, etc. in our old jhipster app. We started at the same time that jhipster introduced the DTO and Mapstruct material. In new projects where we use Jhipster, we always delete all DTOs and virtual machines. First of all: UserVM / DTO material (managed), which is very confusing. This has several reasons:
We will never have a virtual machine on the server side of our applications. In a jhipster application, where the view is entirely based on javascript / angular, a view model must exist. We often have other applications that use the REST API, and these applications are not representations. Therefore, especially in the microservice architecture, I will never call something in the REST-API "view" or even "view-model". Thus, in applications where there is no representation in Java (with JSP or so), you will never find the term “virtual machine” in our Java code. In addition, there may be different types of views (for example, an angular web application, an iOS application, a desktop client or other things), and each of them has different types, view parts, widgets and, therefore, needs other viewing models. Finally, there were some people who said that the REST-API may not provide any things that are not a real resource / entity ...
So, you are absolutely right that the virtual machines in jhipster are actually DTOs. But, as you say, there is a problem with "DTO" because usually a DTO is just a stateless transfer object to encapsulate common values between two or more services (or systems) without any logic. We believe this is also an architectural problem between the top-down (REST) managed API and bottom-up, which are somehow mixed in JHipster applications. Like your opinion, I believe that JHipster uses DTO where it should be a domain object (or entity). For instance. the managed user is not a virtual machine or DTO, it is an object. I think the problem is that some people believe that only JPA-based objects are domain objects, and there cannot be other domain objects (objects).
Finally, we decided to introduce a new type called ADO (API data object or access data object) because we did not find a suitable condition. ADO is compared to jhipster VM, DTO or even without any logic. The usual "API layer" only reads and writes ADO. This level is used for REST API controllers, as well as for the Java API, which can be used by plugins. This gives us the ability to send all ADOs using the client-API without adding any specific internal or domain objects. Since the REST-API and each plugin use the same ADO (and, therefore, the same description and structure), developers are not confused, and resource-oriented external layers are properly separated from internal layers that use a different business logic based on.
Everything else that is part of the internal level, such as entities, derived entities, subsets or supersets of entities, are basically domain objects. Therefore, we therefore removed all virtual machines and DTOs from this inner layer, business logic, and so on.
In sum: To encapsulate internal (JPA) entities from external access, we use ADO, as there may be other than just views. These ADOs apply to jhipster virtual machines as well as DTOs. But internally, beyond the general API level, we never use DTO or VM or even ADO, because these objects are mainly domain objects.