is it possible to pass a parameter in a service that allows me to use one method rather than another?
Below is a controller and a service. I want to pass a (persistenceType) parameter that allows me to use mybatis rather than jpa. I'll pass it as queryparam in the REST call.
@Service
public class ManufacturerService implements IManufacturerService {
@Autowired
private ManufacturerRepository manufacturerRepository;
@Autowired
private ManufacturerMapper manufacturerMapper;
@Override
@Transactional
public Manufacturer save(Manufacturer manufacturer) {
//if persistenceType.equals(MYBATIS)
//manufacturerMapper.insert(manufacturer);
//else manufacturerRepository.save(manufacturer);
manufacturerMapper.insert(manufacturer);
return null;
//return manufacturerRepository.save(manufacturer);
}
}
@RestController
@RequestMapping("/manufacturers")
public class ManufacturesController {
public static final Logger LOG = LogManager.getLogger(ManufacturesController.class);
@Autowired
private ManufacturerService manufacturerService;
@PostMapping
public ResponseEntity<Manufacturer> createManufacturer(@RequestBody ManufacturerDTO manufacturer, @Param persistenceType) {
LOG.info("START - createManufacturer");
try {
Manufacturer _manufacturer = ManufacturerMapper.toEntity(manufacturer);
manufacturerService(persistenceType).save(_manufacturer);
LOG.info("STOP - createManufacturer");
return new ResponseEntity<>(_manufacturer, HttpStatus.CREATED);
} catch (Exception e) {
LOG.error("Error description: ", e);
LOG.info("STOP - createManufacturer");
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
I know it's not like that, but it was right to make you understand what my purpose is.
CodePudding user response:
If you specify a property in your application.properties
file that corresponds to the persistenceType
, that will allow you to dynamically switch between mybatis
and jpa
.
For more information, there are some docs here:
https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.external-config
CodePudding user response:
It is perfectly possible. I would start by creating a PersistenceType
enum:
enum PersistenceType {
JPA,
MYBATIS
}
Then you need to declare you need to receive a PersistenceType
in your POST endpoint and pass it to the underlying ManufacturerService
as follows:
@RestController
@RequestMapping("/manufacturers")
public class ManufacturesController {
public static final Logger LOG = LogManager.getLogger(ManufacturesController.class);
@Autowired
private ManufacturerService manufacturerService;
@PostMapping
public ResponseEntity<Manufacturer> createManufacturer(@RequestBody ManufacturerDTO manufacturer, @RequestParm(required = true) PersistenceType persistenceType) {
LOG.info("START - createManufacturer");
try {
Manufacturer _manufacturer = ManufacturerMapper.toEntity(manufacturer);
manufacturerService.save(_manufacturer, persistenceType);
LOG.info("STOP - createManufacturer");
return new ResponseEntity<>(_manufacturer, HttpStatus.CREATED);
} catch (Exception e) {
LOG.error("Error description: ", e);
LOG.info("STOP - createManufacturer");
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
The final thing is to change your ManufacturerService
to accept an additional parameter in the save method:
@Service
public class ManufacturerService implements IManufacturerService {
@Autowired
private ManufacturerRepository manufacturerRepository;
@Autowired
private ManufacturerMapper manufacturerMapper;
@Override
@Transactional
public Manufacturer save(Manufacturer manufacturer, PersistenceType persistenceType) {
if (persistenceType.equals(PersistenceType.MYBATIS)) {
return manufacturerMapper.insert(manufacturer);
} else {
return manufacturerRepository.save(manufacturer);
}
}
}
As a suggestion, I would include persistenceType
in the request body and not as a separate query param. It works as-is, but it would be more concise and easier to understand for the consumer of your API if everything is passed in the request body (or as a path variable).