Orika - 将第 <T> 页映射到第 <TDto> 页
Orika - map Page<T> to Page<TDto>
我在将 Page 对象映射到 Page 对象时遇到问题。
我有以下映射器 class:
package com.agileplayers.agilemanager.core.mapper;
import com.agileplayers.agilemanager.core.domain.Account;
import com.agileplayers.agilemanager.core.domain.Entry;
import com.agileplayers.agilemanager.core.dto.AccountDto;
import com.agileplayers.agilemanager.core.dto.EntryDto;
import ma.glasnost.orika.MapperFacade;
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.impl.DefaultMapperFactory;
import ma.glasnost.orika.metadata.TypeBuilder;
import org.springframework.data.domain.PageImpl;
import org.springframework.stereotype.Component;
@Component
public class Mapper {
final static MapperFactory MAPPER_FACTORY = new DefaultMapperFactory.Builder().build();
public MapperFacade getMapperFacade(){
registerMappers();
return MAPPER_FACTORY.getMapperFacade();
}
private void registerMappers(){
MAPPER_FACTORY.classMap(Entry.class, EntryDto.class)
.byDefault()
.register();
MAPPER_FACTORY.classMap(Account.class, AccountDto.class)
.byDefault()
.register();
MAPPER_FACTORY.classMap(
new TypeBuilder<PageImpl<Entry>>() {}.build(),
new TypeBuilder<PageImpl<EntryDto>>() {}.build())
.byDefault()
.register();
}
}
此处使用:
@Autowired
private EntryRepository entryRepository;
private void start() {
Mapper mapper = new Mapper();
Page<Entry> entryPage = entryRepository.findAll(new PageRequest(0, 2));
Type<Page<Entry>> pageEntryType = new TypeBuilder<Page<Entry>>() {
}.build();
Type<Page<EntryDto>> pageEntryDtoType = new TypeBuilder<Page<EntryDto>>() {
}.build();
Page<EntryDto> entryDtoPage = mapper.getMapperFacade().map(entryPage, pageEntryType, pageEntryDtoType);
不幸的是,我收到以下信息:
Exception in thread "main" ma.glasnost.orika.MappingException: While attempting the following mapping:
sourceClass = class org.springframework.data.domain.PageImpl
sourceType = org.springframework.data.domain.Page<Entry>
destinationType = org.springframework.data.domain.Page<EntryDto>
resolvedStrategy = InstantiateAndUseCustomMapperStrategy<PageImpl<Entry>, PageImpl<EntryDto>> {customMapper: GeneratedMapper<PageImpl<Entry>, PageImpl<EntryDto>> {usedConverters: [], usedMappers: [], usedMapperFacades: [DefaultBoundMapperFacade<Sort, Sort>], usedTypes: [Object] }, unenhancer: ma.glasnost.orika.unenhance.BaseUnenhancer@4b5aa48b, objectFactory: ma.glasnost.orika.generated.PageImpl_PageImpl_ObjectFactory59678627946495970211838179@2dd2ff87}
Error occurred: java.lang.UnsupportedOperationException
-----begin dump of current state-----------------------------
Registered object factories: 3 (approximate size: 9,541.1 kB)
[AccountDto] : {Account=DefaultConstructorObjectFactory<AccountDto>}
[PageImpl<EntryDto>] : {PageImpl<Entry>=ma.glasnost.orika.generated.PageImpl_PageImpl_ObjectFactory59678627946495970211838179@2dd2ff87}
[EntryDto] : {Entry=DefaultConstructorObjectFactory<EntryDto>}
-------------------------------------------------------------
Registered mappers: 3 (approximate size: 9,794.2 kB)
[0] : GeneratedMapper<PageImpl<Entry>, PageImpl<EntryDto>> {usedConverters: [], usedMappers: [], usedMapperFacades: [DefaultBoundMapperFacade<Sort, Sort>], usedTypes: [Object] }
[1] : GeneratedMapper<Entry, EntryDto> {usedConverters: [builtin:CloneableConverter(Copy by cloning:Date, Calendar, XMLGregorianCalendar)], usedMappers: [], usedMapperFacades: [DefaultBoundMapperFacade<Account, AccountDto>], usedTypes: [Date] }
[2] : GeneratedMapper<Account, AccountDto> {usedConverters: [builtin:CloneableConverter(Copy by cloning:Date, Calendar, XMLGregorianCalendar)], usedMappers: [], usedMapperFacades: [], usedTypes: [Date, Entry, EntryDto] }
-------------------------------------------------------------
Registered concrete types: 6 (approximate size: 346.9 kB)
[interface java.util.Collection] : ArrayList<Object>
[interface java.util.Map] : LinkedHashMap<Object, Object>
[interface java.util.Map$Entry] : MapEntry<Object, Object>
[Page<Entry>] : PageImpl<EntryDto>
[interface java.util.List] : ArrayList<Object>
[interface java.util.Set] : LinkedHashSet<Object>
-------------------------------------------------------------
Resolved strategies: 4 (approximate size: 9,794.6 kB)
{source: PageImpl, dest: Page<EntryDto>, in-place:false}: InstantiateAndUseCustomMapperStrategy<PageImpl<Entry>, PageImpl<EntryDto>> {customMapper: GeneratedMapper<PageImpl<Entry>, PageImpl<EntryDto>> {usedConverters: [], usedMappers: [], usedMapperFacades: [DefaultBoundMapperFacade<Sort, Sort>], usedTypes: [Object] }, unenhancer: ma.glasnost.orika.unenhance.BaseUnenhancer@4b5aa48b, objectFactory: ma.glasnost.orika.generated.PageImpl_PageImpl_ObjectFactory59678627946495970211838179@2dd2ff87}
{source: Account, dest: AccountDto, in-place:false}: InstantiateAndUseCustomMapperStrategy<Account, AccountDto> {customMapper: GeneratedMapper<Account, AccountDto> {usedConverters: [builtin:CloneableConverter(Copy by cloning:Date, Calendar, XMLGregorianCalendar)], usedMappers: [], usedMapperFacades: [], usedTypes: [Date, Entry, EntryDto] }, unenhancer: ma.glasnost.orika.unenhance.BaseUnenhancer@4b5aa48b, objectFactory: DefaultConstructorObjectFactory<AccountDto>}
{source: Entry, dest: Object, in-place:false}: InstantiateAndUseCustomMapperStrategy<Entry, EntryDto> {customMapper: GeneratedMapper<Entry, EntryDto> {usedConverters: [builtin:CloneableConverter(Copy by cloning:Date, Calendar, XMLGregorianCalendar)], usedMappers: [], usedMapperFacades: [DefaultBoundMapperFacade<Account, AccountDto>], usedTypes: [Date] }, unenhancer: ma.glasnost.orika.unenhance.BaseUnenhancer@4b5aa48b, objectFactory: DefaultConstructorObjectFactory<EntryDto>}
{source: Entry, dest: EntryDto, in-place:false}: InstantiateAndUseCustomMapperStrategy<Entry, EntryDto> {customMapper: GeneratedMapper<Entry, EntryDto> {usedConverters: [builtin:CloneableConverter(Copy by cloning:Date, Calendar, XMLGregorianCalendar)], usedMappers: [], usedMapperFacades: [DefaultBoundMapperFacade<Account, AccountDto>], usedTypes: [Date] }, unenhancer: ma.glasnost.orika.unenhance.BaseUnenhancer@4b5aa48b, objectFactory: DefaultConstructorObjectFactory<EntryDto>}
-------------------------------------------------------------
Unenhance strategy: ma.glasnost.orika.unenhance.BaseUnenhancer@4b5aa48b
-----end dump of current state-------------------------------
at ma.glasnost.orika.impl.ExceptionUtility.newMappingException(ExceptionUtility.java:55)
at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:280)
at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:243)
at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:133)
at com.agileplayers.agilemanager.AgileManagerApplication.start(AgileManagerApplication.java:49)
at com.agileplayers.agilemanager.AgileManagerApplication.main(AgileManagerApplication.java:34)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: java.lang.UnsupportedOperationException
at java.util.Collections$UnmodifiableCollection.clear(Collections.java:1074)
at ma.glasnost.orika.generated.Orika_PageImpl_PageImpl_Mapper5970055563717[=14=].mapAtoB(Orika_PageImpl_PageImpl_Mapper5970055563717[=14=].java)
at ma.glasnost.orika.impl.mapping.strategy.UseCustomMapperStrategy.map(UseCustomMapperStrategy.java:67)
at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:266)
... 9 more
Entry映射到EntryDto或List映射到List都没有问题。我认为问题可能出在 PageImpl class 中的无参数构造函数,但这只是我的怀疑。
请指教,我做错了什么。
如果您使用的是 Spring Data Commons 1.10 或更新版本,Page
对象有一个 map
方法。只是利用它来发挥你的优势。
对于下一个示例,我假设您实际上正在使用它。
private void start() {
final Mapper mapper = new Mapper();
Page<Entry> entryPage = entryRepository.findAll(new PageRequest(0, 2));
Page<EntryDto> entryDtoPage = entryPage.map(
new Converter<Entry, EntryDto>() {
public EntryDto convert(Entry source) {
mapper.getMapperFacade().map(source, EntryDto);
}
});
无需提供任何其他代码来尝试 map/hack/reconstruct 实际页面。在 JDK8 上,您可能可以用一个漂亮的 lamda 替换它,从而使代码更小。
Page
对象确实有一个 .map()
方法,所以这很简单:
Page<SomeEntity> daoPage = service.getEntities();
Page<SomeDto> dtoPage = daoPage.map(it -> mapper.map(it, SomeDto.class));
我在将 Page 对象映射到 Page 对象时遇到问题。 我有以下映射器 class:
package com.agileplayers.agilemanager.core.mapper;
import com.agileplayers.agilemanager.core.domain.Account;
import com.agileplayers.agilemanager.core.domain.Entry;
import com.agileplayers.agilemanager.core.dto.AccountDto;
import com.agileplayers.agilemanager.core.dto.EntryDto;
import ma.glasnost.orika.MapperFacade;
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.impl.DefaultMapperFactory;
import ma.glasnost.orika.metadata.TypeBuilder;
import org.springframework.data.domain.PageImpl;
import org.springframework.stereotype.Component;
@Component
public class Mapper {
final static MapperFactory MAPPER_FACTORY = new DefaultMapperFactory.Builder().build();
public MapperFacade getMapperFacade(){
registerMappers();
return MAPPER_FACTORY.getMapperFacade();
}
private void registerMappers(){
MAPPER_FACTORY.classMap(Entry.class, EntryDto.class)
.byDefault()
.register();
MAPPER_FACTORY.classMap(Account.class, AccountDto.class)
.byDefault()
.register();
MAPPER_FACTORY.classMap(
new TypeBuilder<PageImpl<Entry>>() {}.build(),
new TypeBuilder<PageImpl<EntryDto>>() {}.build())
.byDefault()
.register();
}
}
此处使用:
@Autowired
private EntryRepository entryRepository;
private void start() {
Mapper mapper = new Mapper();
Page<Entry> entryPage = entryRepository.findAll(new PageRequest(0, 2));
Type<Page<Entry>> pageEntryType = new TypeBuilder<Page<Entry>>() {
}.build();
Type<Page<EntryDto>> pageEntryDtoType = new TypeBuilder<Page<EntryDto>>() {
}.build();
Page<EntryDto> entryDtoPage = mapper.getMapperFacade().map(entryPage, pageEntryType, pageEntryDtoType);
不幸的是,我收到以下信息:
Exception in thread "main" ma.glasnost.orika.MappingException: While attempting the following mapping:
sourceClass = class org.springframework.data.domain.PageImpl
sourceType = org.springframework.data.domain.Page<Entry>
destinationType = org.springframework.data.domain.Page<EntryDto>
resolvedStrategy = InstantiateAndUseCustomMapperStrategy<PageImpl<Entry>, PageImpl<EntryDto>> {customMapper: GeneratedMapper<PageImpl<Entry>, PageImpl<EntryDto>> {usedConverters: [], usedMappers: [], usedMapperFacades: [DefaultBoundMapperFacade<Sort, Sort>], usedTypes: [Object] }, unenhancer: ma.glasnost.orika.unenhance.BaseUnenhancer@4b5aa48b, objectFactory: ma.glasnost.orika.generated.PageImpl_PageImpl_ObjectFactory59678627946495970211838179@2dd2ff87}
Error occurred: java.lang.UnsupportedOperationException
-----begin dump of current state-----------------------------
Registered object factories: 3 (approximate size: 9,541.1 kB)
[AccountDto] : {Account=DefaultConstructorObjectFactory<AccountDto>}
[PageImpl<EntryDto>] : {PageImpl<Entry>=ma.glasnost.orika.generated.PageImpl_PageImpl_ObjectFactory59678627946495970211838179@2dd2ff87}
[EntryDto] : {Entry=DefaultConstructorObjectFactory<EntryDto>}
-------------------------------------------------------------
Registered mappers: 3 (approximate size: 9,794.2 kB)
[0] : GeneratedMapper<PageImpl<Entry>, PageImpl<EntryDto>> {usedConverters: [], usedMappers: [], usedMapperFacades: [DefaultBoundMapperFacade<Sort, Sort>], usedTypes: [Object] }
[1] : GeneratedMapper<Entry, EntryDto> {usedConverters: [builtin:CloneableConverter(Copy by cloning:Date, Calendar, XMLGregorianCalendar)], usedMappers: [], usedMapperFacades: [DefaultBoundMapperFacade<Account, AccountDto>], usedTypes: [Date] }
[2] : GeneratedMapper<Account, AccountDto> {usedConverters: [builtin:CloneableConverter(Copy by cloning:Date, Calendar, XMLGregorianCalendar)], usedMappers: [], usedMapperFacades: [], usedTypes: [Date, Entry, EntryDto] }
-------------------------------------------------------------
Registered concrete types: 6 (approximate size: 346.9 kB)
[interface java.util.Collection] : ArrayList<Object>
[interface java.util.Map] : LinkedHashMap<Object, Object>
[interface java.util.Map$Entry] : MapEntry<Object, Object>
[Page<Entry>] : PageImpl<EntryDto>
[interface java.util.List] : ArrayList<Object>
[interface java.util.Set] : LinkedHashSet<Object>
-------------------------------------------------------------
Resolved strategies: 4 (approximate size: 9,794.6 kB)
{source: PageImpl, dest: Page<EntryDto>, in-place:false}: InstantiateAndUseCustomMapperStrategy<PageImpl<Entry>, PageImpl<EntryDto>> {customMapper: GeneratedMapper<PageImpl<Entry>, PageImpl<EntryDto>> {usedConverters: [], usedMappers: [], usedMapperFacades: [DefaultBoundMapperFacade<Sort, Sort>], usedTypes: [Object] }, unenhancer: ma.glasnost.orika.unenhance.BaseUnenhancer@4b5aa48b, objectFactory: ma.glasnost.orika.generated.PageImpl_PageImpl_ObjectFactory59678627946495970211838179@2dd2ff87}
{source: Account, dest: AccountDto, in-place:false}: InstantiateAndUseCustomMapperStrategy<Account, AccountDto> {customMapper: GeneratedMapper<Account, AccountDto> {usedConverters: [builtin:CloneableConverter(Copy by cloning:Date, Calendar, XMLGregorianCalendar)], usedMappers: [], usedMapperFacades: [], usedTypes: [Date, Entry, EntryDto] }, unenhancer: ma.glasnost.orika.unenhance.BaseUnenhancer@4b5aa48b, objectFactory: DefaultConstructorObjectFactory<AccountDto>}
{source: Entry, dest: Object, in-place:false}: InstantiateAndUseCustomMapperStrategy<Entry, EntryDto> {customMapper: GeneratedMapper<Entry, EntryDto> {usedConverters: [builtin:CloneableConverter(Copy by cloning:Date, Calendar, XMLGregorianCalendar)], usedMappers: [], usedMapperFacades: [DefaultBoundMapperFacade<Account, AccountDto>], usedTypes: [Date] }, unenhancer: ma.glasnost.orika.unenhance.BaseUnenhancer@4b5aa48b, objectFactory: DefaultConstructorObjectFactory<EntryDto>}
{source: Entry, dest: EntryDto, in-place:false}: InstantiateAndUseCustomMapperStrategy<Entry, EntryDto> {customMapper: GeneratedMapper<Entry, EntryDto> {usedConverters: [builtin:CloneableConverter(Copy by cloning:Date, Calendar, XMLGregorianCalendar)], usedMappers: [], usedMapperFacades: [DefaultBoundMapperFacade<Account, AccountDto>], usedTypes: [Date] }, unenhancer: ma.glasnost.orika.unenhance.BaseUnenhancer@4b5aa48b, objectFactory: DefaultConstructorObjectFactory<EntryDto>}
-------------------------------------------------------------
Unenhance strategy: ma.glasnost.orika.unenhance.BaseUnenhancer@4b5aa48b
-----end dump of current state-------------------------------
at ma.glasnost.orika.impl.ExceptionUtility.newMappingException(ExceptionUtility.java:55)
at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:280)
at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:243)
at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:133)
at com.agileplayers.agilemanager.AgileManagerApplication.start(AgileManagerApplication.java:49)
at com.agileplayers.agilemanager.AgileManagerApplication.main(AgileManagerApplication.java:34)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: java.lang.UnsupportedOperationException
at java.util.Collections$UnmodifiableCollection.clear(Collections.java:1074)
at ma.glasnost.orika.generated.Orika_PageImpl_PageImpl_Mapper5970055563717[=14=].mapAtoB(Orika_PageImpl_PageImpl_Mapper5970055563717[=14=].java)
at ma.glasnost.orika.impl.mapping.strategy.UseCustomMapperStrategy.map(UseCustomMapperStrategy.java:67)
at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:266)
... 9 more
Entry映射到EntryDto或List映射到List都没有问题。我认为问题可能出在 PageImpl class 中的无参数构造函数,但这只是我的怀疑。 请指教,我做错了什么。
如果您使用的是 Spring Data Commons 1.10 或更新版本,Page
对象有一个 map
方法。只是利用它来发挥你的优势。
对于下一个示例,我假设您实际上正在使用它。
private void start() {
final Mapper mapper = new Mapper();
Page<Entry> entryPage = entryRepository.findAll(new PageRequest(0, 2));
Page<EntryDto> entryDtoPage = entryPage.map(
new Converter<Entry, EntryDto>() {
public EntryDto convert(Entry source) {
mapper.getMapperFacade().map(source, EntryDto);
}
});
无需提供任何其他代码来尝试 map/hack/reconstruct 实际页面。在 JDK8 上,您可能可以用一个漂亮的 lamda 替换它,从而使代码更小。
Page
对象确实有一个 .map()
方法,所以这很简单:
Page<SomeEntity> daoPage = service.getEntities();
Page<SomeDto> dtoPage = daoPage.map(it -> mapper.map(it, SomeDto.class));