Spring Boot升级至2.1.5.RELEASE后Page.map方法适配问题求助
Hey there, let's work through this issue step by step to get your code running again after the upgrade!
First: Verify Your Pom.xml Configuration
You mentioned upgrading to Spring Boot 2.1.5.RELEASE, but both your "Now" and "Prior" pom snippets show the parent version as 1.5.7.RELEASE. Before fixing any code, make sure you actually update the parent version in your pom to 2.1.5.RELEASE—without this change, the upgrade won't take effect at all.
Why the Error Happens
The error The method map(Function) in the type Page is not applicable for the arguments (new Converter(){}) stems from a breaking change in Spring Data Commons (which Spring Boot 2.x uses an updated version of):
- In Spring Data 1.x (paired with Boot 1.5.x), the
Page.map()method accepted aorg.springframework.core.convert.converter.Converter - In Spring Data 2.x (paired with Boot 2.x), this method was updated to accept a
java.util.function.Functioninstead, to align with Java 8's functional programming standards.
Fixing the Code
You just need to replace the anonymous Converter implementation with either an anonymous Function or a more concise lambda expression. Here's how to adjust your code:
Original Problem Code
final Page<DutyAllocationDto> dutyAllocationDto = dutyAllocationBean .map(new Converter<DutyAllocationBean, DutyAllocationDto>() { @Override public DutyAllocationDto convert(DutyAllocationBean entity) { DutyAllocationDto dto = new DutyAllocationDto(); ModelMapper modelMapper = new ModelMapper(); dto = modelMapper.map(entity, DutyAllocationDto.class); DutyAllocation dutyAllocation = dutyAllocationFilterRepository .findById(entity.getDutyallocationid()).get(); if (dutyAllocation != null) { dto.setCityName(dutyAllocation.getTblDepotMaster().getCityMaster().getCityName()); } if(dto.getRoutenumber()!=null) { Tblroutemaster route=tblroutemasterRepository.findByrouteNumber(Long.valueOf(dto.getRoutenumber())); if(route!=null) { dto.setRouteName(route.getRouteName()); } } return dto; } });
Fixed Code (Using Anonymous Function)
final Page<DutyAllocationDto> dutyAllocationDto = dutyAllocationBean .map(new Function<DutyAllocationBean, DutyAllocationDto>() { @Override public DutyAllocationDto apply(DutyAllocationBean entity) { DutyAllocationDto dto = new DutyAllocationDto(); ModelMapper modelMapper = new ModelMapper(); dto = modelMapper.map(entity, DutyAllocationDto.class); DutyAllocation dutyAllocation = dutyAllocationFilterRepository .findById(entity.getDutyallocationid()).get(); if (dutyAllocation != null) { dto.setCityName(dutyAllocation.getTblDepotMaster().getCityMaster().getCityName()); } if(dto.getRoutenumber()!=null) { Tblroutemaster route=tblroutemasterRepository.findByrouteNumber(Long.valueOf(dto.getRoutenumber())); if(route!=null) { dto.setRouteName(route.getRouteName()); } } return dto; } });
Even Cleaner: Use Lambda Expression
Since Function is a functional interface, you can simplify the code with a lambda to make it shorter and more readable:
final Page<DutyAllocationDto> dutyAllocationDto = dutyAllocationBean .map(entity -> { DutyAllocationDto dto = new ModelMapper().map(entity, DutyAllocationDto.class); DutyAllocation dutyAllocation = dutyAllocationFilterRepository .findById(entity.getDutyallocationid()).get(); if (dutyAllocation != null) { dto.setCityName(dutyAllocation.getTblDepotMaster().getCityMaster().getCityName()); } if(dto.getRoutenumber()!=null) { Tblroutemaster route=tblroutemasterRepository.findByrouteNumber(Long.valueOf(dto.getRoutenumber())); if(route!=null) { dto.setRouteName(route.getRouteName()); } } return dto; });
Bonus Optimization
Creating a new ModelMapper instance every time inside the mapping function is inefficient. Instead, inject ModelMapper as a bean into your class and reuse it:
// Inject ModelMapper via constructor (preferred) or @Autowired private final ModelMapper modelMapper; public YourServiceClass(ModelMapper modelMapper, DutyAllocationFilterRepository dutyAllocationFilterRepository, TblroutemasterRepository tblroutemasterRepository) { this.modelMapper = modelMapper; this.dutyAllocationFilterRepository = dutyAllocationFilterRepository; this.tblroutemasterRepository = tblroutemasterRepository; } // Then use the reused ModelMapper in the map function final Page<DutyAllocationDto> dutyAllocationDto = dutyAllocationBean .map(entity -> { DutyAllocationDto dto = modelMapper.map(entity, DutyAllocationDto.class); // rest of your mapping logic... return dto; });
内容的提问来源于stack exchange,提问作者Arpan Jain

