Hi,
By design DTOAssembler.newAssembler() solves the following problems:
1. Creating the binding between classes via pipes (obviously)
2. Provides weakhashmap caching for class pair for specific class loader (this helps to avoid OOM in applications with lots of DTO assembler as weak hash map would allow GC if resources are low)
3. Do dynamic polymorphic binding (this is because entity can be class or interface, or even auto generated class like CGLib one in Hibernate e.g. DTOAssembler.newAssembler(UserDTO.class, entity.getClass()).assembleDto(), so you determine the entity binding at runtime)
In your example you are using only #1 - basic binding.
#2 - is no longer working as you have a hard reference to assembler instance and it will not be GC’ed
#3 - you are not using as you have a specific binding between UserDTO.class and UserEntity.class
As mentioned in doc’s GeDA is not a mapper it is much more, it is a smart DTO assembler.
I am not sure if any of this applies to your project but these are very important features that are unique to GeDA that save the day in some of the unusual project setups.
Hope this helps, and if want you can share this email thread in Google groups as you mentioned yourself it might be useful to someone (you have been added as a member)
Regards,
Denis
P.S. regarding readability you can always extract the call to a private method:
private final UserRepository userRepository;
@Autowired
public UserController(UserRepository userRepository) {
this.userRepository = userRepository;
}
@RequestMapping(path = "/user", produces = "application/json", method = RequestMethod.GET)
@ResponseBody
public List<UserDTO> getAllUsers() {
Iterable<UserEntity> users = userRepository.findAll();
if (!users.iterator().hasNext()) {
// dont have any users yet, create one just for demo
UserEntity user = new UserEntity();
user.setName("Hans Maier");
userRepository.save(user);
users = userRepository.findAll();
}
List<UserEntity> userList = StreamSupport.stream(users.spliterator(), false).collect(Collectors.toList());
return assembleDto(userList);
}
private List<UserDTO> assembleDto(List<UserEntity> userList) {
List<UserDTO> result = new ArrayList<>();
DTOAssembler.newAssembler(UserDTO.class, UserEntity.class, UserEntity.class.getClassLoader()).assembleDtos(result, userList, null, null);
return result;
}
Hi
Thanks a lot for the very fast response. Actually, I could fix this also via adapting the construction in the controller constructor. (which makes the code easier to read). Are there arguments against creating the assembler in the constructor?
Also It would be good to also mention this somewhere in the wiki, I checked there but since the OSGi argument did not seem to apply to me I did not look too close there.
@Controller
@Transactional(readOnly = true)
class UserController {
private final Assembler userAssembler;
private final UserRepository userRepository;
@Autowired
public UserController(UserRepository userRepository) {
this.userRepository = userRepository;
userAssembler = DTOAssembler.newAssembler(UserDTO.class, UserEntity.class, UserEntity.class.getClassLoader());
}