I am somewhat new to Spring and have recently generated a JHipster monolith application with the WebFlux option. My current aim is to make it compatible with Firestore and implement some missing features like inserting document references. To do so, I am currently having the following structure:
Device
" which holds a field String firmwareType;
FirmwareType
"FirmwareType firmwareType;
Correspondingly, I also have the corresponding Repository (extending FirestoreReactiveRepository
which extends ReactiveCrudRepository
) and Controller implementations, which all work fine. To perform the conversion from a "full object" of FirmwareType in the DTO-object to a String firmwareTypeId;
in the Device-object, I implemented a MapStruct Mapper :
@Mapper(unmappedTargetPolicy = org.mapstruct.ReportingPolicy.IGNORE, componentModel = "spring")
public abstract class DeviceMapper {
private final Logger logger = LoggerFactory.getLogger(DeviceMapper.class);
@Autowired
protected FirmwareTypeRepository fwTypeRepo;
public abstract Device dtoToDevice(DeviceDTO deviceDTO);
public abstract DeviceDTO deviceToDto(Device device);
public abstract List<DeviceDTO> devicesToDTOs(List<Device> devices);
public abstract List<Device> dtosToDevices(List<DeviceDTO> dtos);
public String map(FirmwareType value) {
if (value == null || value.getId() == null || value.getId().isEmpty()) {
return null;
}
return value.getId();
}
public FirmwareType map(String value) {
if (value == null || value.isEmpty()) {
return null;
}
return fwTypeRepo.findById(value).block(); // <<-- this gets stuck!
}
}
The FirmwareTypeRepository which is autowired as fwTypeRepo field:
@Repository
public interface FirmwareTypeRepository extends FirestoreReactiveRepository<FirmwareType> {
Mono<FirmwareType> findById(String id);
}
The corresponding map functions get called perfectly fine, but the fwTypeRepo.findById(..)
call in the marked line (third-last line) seems to get stuck somewhere and never returns or throws an error. When the "fwTypeRepo" via its Controller-endpoint is called, it works without any issues.
I suppose it must be some kind of calling context issue or something? Is there another way to force a result by Mono synchronously than block?
Thanks for your help in advance, everyone!
Edit: At this point, I am sure it has something to do with Autowiring the Repository. It seems to not correctly do so / use the correct instance. While a customized Interface+Impl is called correctly, the underlying logic (from FirestoreReactive/ReactiveCrudRepository) doesn't seem to supply data correctly (also when @Autowire is used in other components.). I found some hints pointing at the package-structure but (ie Application class needs to be in a root package) but that isn't an issue.
Mapstruct is not reactive as i know so this approach won't work, you'll need mapstruct to return a mono that builds the object itself but that wouldn't make sense as it's a mapping lib which is only for doing blocking things.
Could try use 2 Mono/Mappers, 1 for each DB call and then just Mono.zip(dbCall1, dbCall2) and set the the mapped db call output into the other objects field.
var call1 = Mono.fromFuture(() -> db.loadObject1()).map(o -> mapper1.map(o));
var call2 = Mono.fromFuture(() -> db.loadObject2()).map(o -> mapper2.map(o));
Mono.zip(call1, call2)
.map(t -> {
var o1 = t.getT1();
var o2 = t.getT2();
o1.setField(o2);
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.