Fwd: high - support by Rainer Burgstaller

15 views
Skip to first unread message

Rainer Burgstaller

unread,
Mar 27, 2016, 1:55:10 AM3/27/16
to geda-generic-dto-asse...@googlegroups.com
Sharing on the public google group in case anyone else comes across this problem.

My Problem was a 
java.lang.ClassCastException: com.example.UserEntity cannot be cast to com.example.UserEntity
    at com.example.UserEntityDataReaderMgetIdIDjavassist.read(UserEntityDataReaderMgetIdIDjavassist.java) ~[geda.core-3.1.0.jar:na]
    at com.inspiresoftware.lib.dto.geda.assembler.DataPipe.writeFromEntityToDto(DataPipe.java:144) ~[geda.core-3.1.0.jar:na]
    at com.inspiresoftware.lib.dto.geda.assembler.DTOtoEntityAssemblerImpl.assembleDto(DTOtoEntityAssemblerImpl.java:240) ~[geda.core-3.1.0.jar:na]
    at com.inspiresoftware.lib.dto.geda.assembler.DTOtoEntityAssemblerImpl.assembleDtos(DTOtoEntityAssemblerImpl.java:262) ~[geda.core-3.1.0.jar:na]
in my SpringBoot Application.

Denis Pavlov was kind enough to provide a very thorough answer and solution. For more information see below:

---------- Forwarded message ----------
From: Denis Pavlov <denis.v...@inspire-software.com>
Date: Wed, Mar 23, 2016 at 9:12 AM
Subject: Re: high - support by Rainer Burgstaller
To: Rainer Burgstaller <rbu...@gmail.com>


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;
}



On 23 Mar 2016, at 05:47, Rainer Burgstaller <rbu...@gmail.com> wrote:

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());
}



On Tue, Mar 22, 2016 at 1:52 PM, Denis Pavlov <denis.v...@inspire-software.com> wrote:
Hi,

Your issue is with class loaders. Do not pre-create assemblers, DTOAssembler has built in caching, just do the following

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());
List<UserDTO> result = new ArrayList<>();
DTOAssembler.newAssembler(UserDTO.class, UserEntity.class, UserEntity.class.getClassLoader()).assembleDtos(result, userList, null, null);
return result;
}
Regards,
Denis


On 22 Mar 2016, at 05:44, Rainer Burgstaller <rbu...@gmail.com> wrote:

Hi
I have been using GeDA in the past and it was working very well. Now I try to use it in a spring boot project and I am seeing ClassCastException when trying to map a hibernate entity. Sample to reproduce is on github: https://github.com/rburgst/SpringBootGeda

Any help would be appreciated.

best regards
- Rainer Burgstaller




Rainer Burgstaller

unread,
Apr 4, 2016, 12:37:22 PM4/4/16
to GeDA Generic DTO Assembler discussion group
While initially with my playground example this approach worked well, I am now running across lots of class loading problems in case the DTO contains other custom classes.

I run into problems where while I specify the class loader for the UserEntity, then it complains about the UserDTO.class or some child field thereof. 

Not sure whether this is caused by spring dev tools (which do mess with the class loader) or whether this is some general problem.

Not sure whether there is a solution.

any advice would be appreciated.

thanks
- Rainer
Reply all
Reply to author
Forward
0 new messages