Home > Blockchain >  Pass a parameter in a service that allows me to use one method rather than another method
Pass a parameter in a service that allows me to use one method rather than another method

Time:12-02

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).

  • Related