How to use DTO in JSF + Spring + Hibernate

老子叫甜甜 提交于 2019-11-27 22:33:16
BalusC

DTO stands for Data Transfer Object. It's supposed to be a plain vanilla Javabean class without any API/architecture specific restrictions such as JSF, JPA or Spring annotations. I.e. it should not contain any import or FQN pointing to an external API. The sole goal is to be able to pass data between different architectures of a big modular webapplication.

For example, if you don't want to use a JPA/Hibernate entity bean as model property of a JSF managed bean and view because they may not be passed beyond the EJB class due to some overly restrictive business or modularity reasons, then you need to create a copy of this class and map the loose properties yourself. Basically:

UserEntity userEntity = em.find(UserEntity.class, id);
UserDTO userDTO = new UserDTO();
userDTO.setId(userEntity.getId());
userDTO.setName(userEntity.getName());
// ...
return userDTO;

There are plenty of libraries available which makes bean-to-bean mapping easy in following way:

SomeLibary.map(userEntity, userDTO);

However, for the average webapplication you don't need DTOs. You're already using JPA entities. You can just go ahead with using them in your JSF bean/view.

This question alone already indicates that you actually don't need DTOs at all. You are not blocked by some specific business restrictions. You should not then search for design patterns so that you can apply it on your project. You should rather search for real problems in form of overcomplicated/unmaintainable/duplicated code so that you can ask/find a suitable design pattern for it. Usually, refactoring duplicate code almost automatically introduces new design patterns without you actually realizing it.

A good example is when a JPA entity is "too large" for the particular purpose (i.e. the entity contains way much more properties than you actually need). Having a lot of those partially used entities is a waste of server memory. To solve this, you could create a DTO class/subclass based on only a few of its properties which you create and fill using constructor expression in JPQL.

See also:

There are two options for populating DTOs - manually, or using an utility like commons-beanutils or Dozer.

The general idea behind DTOs is that they are used to transfer data across layers of the architecture - most often layers that are loosely coupled, for example through web-services or JMS. DTOs can also be used in views, so that the web-layer gets objects that it can use to display to the user and these are different from the entities, in order to avoid entity state management problems and mapping mess.

But for the typical application I would argue that DTOs are unnecessary. Use your entities in your JSF beans and views, just be careful with a possible LazyInitializationException. My experiences shows that entities can be used as DTOs (without the need of a new class) in most of the cases, with slightly more care. And wherever I've seen DTOs in smaller projects, they only complicated things unnecessarily.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!