I got a weird ClassCastException when matching an entity with a DTO with Orika in the Spring Boot webapp sample I'm working on. I get an exception when I try to match in a deployed application in the built-in Tomcat, but I can make the mapping just fine in the context of the JUnit test. These are the corresponding classes (they are all very simple):
JPA Essence:
@Entity public class Position { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private String name;
DTO:
public class PositionDto { private Integer id; private String name;
Stop Controller:
@RestController public class PositionController { @Autowired private PositionService positionService; @RequestMapping("/position") public PositionDto get() { final PositionDto positionDto = positionService.getPosition(1); return positionDto; } }
Class of service:
@Service public class PositionServiceImpl implements PositionService { @Autowired private PositionRepository positionRepository; @Autowired private OrikaBeanMapper mapper; @Transactional(readOnly = true) @Override public PositionDto getPosition(final Position.ID id) {
Class OrikaBeanMapper:
@Component public class OrikaBeanMapper extends ConfigurableMapper implements ApplicationContextAware { public OrikaBeanMapper() { super(false); } @Override protected void configureFactoryBuilder(final DefaultMapperFactory.Builder factoryBuilder) { factoryBuilder.mapNulls(false); }
And this is a stacktrace ClassCastException:
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is ma.glasnost.orika.MappingException: While attempting the following mapping: sourceClass = class com.dlizarra.startuphub.position.Position destinationType = com.dlizarra.startuphub.position.PositionDto resolvedStrategy = InstantiateAndUseCustomMapperStrategy<Position, PositionDto> {customMapper: GeneratedMapper<Position, PositionDto> {usedConverters: [], usedMappers: [], usedMapperFacades: [], usedTypes: [] }, unenhancer: ma.glasnost.orika.unenhance.BaseUnenhancer@73c3e10e , objectFactory: DefaultConstructorObjectFactory<PositionDto>} Error occurred: java.lang.ClassCastException: com.dlizarra.startuphub.position.Position cannot be cast to com.dlizarra.startuphub.position.Position -----begin dump of current state----------------------------- Registered object factories: 1 (approximate size: 110.8 kB) [PositionDto] : {Position=DefaultConstructorObjectFactory<PositionDto>} ------------------------------------------------------------------------------- Registered mappers: 1 (approximate size: 17,643.0 kB) [0] : GeneratedMapper<Position, PositionDto> {usedConverters: [], usedMappers: [], usedMapperFacades: [], usedTypes: [] } ------------------------------------------------------------------------------- Registered concrete types: 5 (approximate size: 294.3 kB) [interface java.util.List] : ArrayList<Object> [interface java.util.Set] : LinkedHashSet<Object> [interface java.util.Collection] : ArrayList<Object> [interface java.util.Map] : LinkedHashMap<Object, Object> [interface java.util.Map$Entry] : MapEntry<Object, Object> ------------------------------------------------------------------------------- Resolved strategies: 1 (approximate size: 19,850.8 kB) {source: Position, dest: PositionDto, in-place:false}: InstantiateAndUseCustomMapperStrategy<Position, PositionDto> {customMapper: GeneratedMapper<Position, PositionDto> {usedConverters: [], usedMappers: [], usedMapperFacades: [], usedTypes: [] }, unenhancer: ma.glasnost.orika.unenhance.BaseUnenhancer@73c3e10e , objectFactory: DefaultConstructorObjectFactory<PositionDto>} ------------------------------------------------------------------------------- Unenhance strategy: ma.glasnost.orika.unenhance.BaseUnenhancer@73c3e10e -----end dump of current state-------------------------------] with root cause java.lang.ClassCastException: com.dlizarra.startuphub.position.Position cannot be cast to com.dlizarra.startuphub.position.Position at ma.glasnost.orika.generated.Orika_PositionDto_Position_Mapper43322711137530$0.mapAtoB(Orika_PositionDto_Position_Mapper43322711137530$0.java) ~[orika-core-1.4.6.jar:na] at ma.glasnost.orika.impl.mapping.strategy.UseCustomMapperStrategy.map(UseCustomMapperStrategy.java:67) ~[orika-core-1.4.6.jar:na] at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:742) ~[orika-core-1.4.6.jar:na]
I really don’t know what is going on here. I do not understand where he is trying to relate the position to the position. This happens with every entity / dto class, not just a position.
I can match any of these classes without problems, when I test the module using any method, it works fine and all fields are displayed correctly, so I don't think this is Orika's configuration problem. An exception occurs only when I have a webapp deployed in the built-in Tomcat, and the mapping method is called as part of the residual controller method.
This is a simple Spring boot application, and this is the first resting point I wrote in it. Maybe I'm missing something in the configuration (I have @EnableAutoConfiguration, so not much to configure), but I can't figure out what Orika is throwing this exception.
Any ideas or tips on what might happen here would be greatly appreciated.
Thanks!