2015-10-25 60 views
6

Örnek Spring Boot webapp'unda Orika ile bir varlığın bir DTO'ya eşleştirilmesi sırasında garip bir ClassCastException yaşıyorum. Yerleştirilen Tomcat uygulamasında dağıtılan uygulamada eşleme yapmayı denediğimde istisna yapıyorum, ancak JUnit test bağlamında eşleme işlemini gayet iyi yapabilirim. Bu (hepsi çok basit) ilgili sınıflara şunlardır:Spring Boot webapp'da Orika ClassCastException

JPA varlık:

@Entity 
public class Position { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Integer id; 
    private String name; 
    // getters/setters... 
} 

DTO:

public class PositionDto { 

    private Integer id; 
    private String name; 
    // getters/setters... 
} 

istirahat kontrolörü:

@RestController 
public class PositionController { 

    @Autowired 
    private PositionService positionService; 

    @RequestMapping("/position") 
    public PositionDto get() { 
     final PositionDto positionDto = positionService.getPosition(1); 
     return positionDto; 
    } 
} 

Hizmet sınıfı:

@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) { 
     // This returns a populated Position object with id=1 and name = "Creator" 
     final Position position = positionRepository.findOne(id.getId()); 
     // This is where the mapping occurs 
     return mapper.map(position, PositionDto.class); 
    } 
} 

OrikaBeanMapper sınıfı:

@Component 
public class OrikaBeanMapper extends ConfigurableMapper implements ApplicationContextAware {   

    public OrikaBeanMapper() { 
     super(false); 
    } 

    @Override 
    protected void configureFactoryBuilder(final DefaultMapperFactory.Builder factoryBuilder) { 
     factoryBuilder.mapNulls(false); 
    } 
    // Omitted non-important methods 

} 

Ve bu ClassCastException ait StackTrace: Ben gerçekten burada neler olduğunu hiç bir fikrim yok

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: [email protected], 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: 
[email protected], objectFactory: 
DefaultConstructorObjectFactory<PositionDto>} 
------------------------------------------------------------------------------- 
Unenhance strategy: [email protected] 
-----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] 

. Pozisyonu Konumlandırmaya nereye koymaya çalıştığımı anlamıyorum. Bu sadece Pozisyon ile değil, her varlık/dto sınıfı ile olur.

Bu sınıflardan herhangi birini herhangi bir yöntemi test ederken hiç sorun yaşamadan eşleştirebilirim, mükemmel çalışır ve tüm alanlar doğru şekilde eşlenir, bu yüzden bir Orika konfigürasyon sorunu olduğunu düşünmüyorum. Özel durum, yalnızca gömülü Tomcat'te dağıtılan web sunucusuna sahip olduğumda ve haritalama yöntemi geri kalan denetleyici yönteminde çağrıldığında gerçekleşir.

Bu basit bir Spring Boot uygulamasıdır ve bu yazdığım ilk dinlenme noktasıdır. Belki de yapılandırmada bir şey eksik (@EnableAutoConfiguration var, bu yüzden yapılandırmak için çok fazla değil), ama Orika bu istisnayı ne yaptığını tahmin edemiyorum.

Burada neler olabileceği hakkında herhangi bir fikir veya ipucu çok takdir edilecektir.

Teşekkürler!

+4

Spring Boot's Dev Tools kullanıyor musunuz?[Bu bilinen sorun] isabet ediyor gibi geliyor (https://github.com/spring-projects/spring-boot/issues/3697). –

+0

Vay bu zor biriydi, teşekkürler Andy. Evet, Dev Tools, Orika 1.4.6 ve Boot 1.3.0 M5 kullanıyorum. Artık, ClassCastException öğesinin Konumdan Konum'a, her sınıfın farklı bir sınıf yükleyicisi tarafından yüklenmesinden kaynaklandığını anlıyorum. Bir çözüm üzerinde çalıştığınızı görebiliyorum, çünkü sadece Orika'da değil, Orika'daki çocuklar da konuya değiniyor ve 1.5 için sabitlenmiş olabilir. –

+0

@AndyWilkinson ve David Size şu anda büyük bir adam öpücüğü verebilirim. Bunun için kaç saat harcadığımdan emin değilim ... ama düşünmek için titriyorum. Eşleştirme, ünite testlerinde mükemmel çalıştı, dev/live run'da hiç zar yoktu. Bu yazıya tökezledikçe, diğer kırmızı sapanları her türlü takip ediyordum. şerefe – wired00

cevap

4

Birkaç ay önce Spring Tool 1.4.0 ile (bu sürümün bu sürüm olduğuna inanıyorum), Dev Tools'un bir özellik dosyası üzerinden özelleştirilebilme olasılığını tanıttıktan sonra, bu hata için bir çözüm olduğunu anladım.

  1. src/main/resources bir META-INF klasör oluşturun:

    için biz sadece var bu sorunu çözmek için.
  2. İçinde spring-devtools.properties dosyası oluşturun. Dosya için restart.include.orika=/orika-core.*\.jar ekleyin. Docs belirtildiği üzere

, restart.include 'yeniden başlatma' classloader içine Regex eşleşen herhangi kavanoz yukarı çeker. Yani örneğin orika-core-1.4.6.jar dosyasını ekliyoruz.

+0

Bu benim için mükemmel çalıştı, bu github sorunu umarım ki orika adamlar bunu düzeltebilirsiniz. Bu adımları takip ederek uygulamanızı tam olarak yeniden başlatın> mutlu günler. – wired00