Reputation: 65
Where is the best place for setting parent entity? In the other word, where is the best place to put entity together?
In the controller, finding parent entity and setting to child then saving?
@RestController
public class SomeController{
@Autowired
private SomeService someService;
@PostMapping("/parents/{parentEntityId}/childs")
public ResponseEntity<Void> save(@PathVariable("parentEntityId") Long parentEntityId, @RequestBody ChildDto childDto) {
Optional<ParentEntity> parentEntity = someService.findParentById(parentEntityId);
if (parentEntity.isPresent()) {
ChildEntity childEntity = childDtoMapper.fromDto(childDto);
childEntity.setParent(parentEntity.get());
someService.saveChild(childEntity);
return ResponseEntity.created(...).build();
}
throw new EntityNotFoundException("Parent entity not found!");
}
}
OR
In the controller, map dto to entity then send entity and parent entity id to service then find parent entity by id and set to child and save?
@RestController
public class SomeController {
@Autowired
private SomeService someService;
@PostMapping("/parents/{parentEntityId}/childs")
public ResponseEntity<Void> save(@PathVariable("parentEntityId") Long parentEntityId, @RequestBody ChildDto childDto) {
ChildEntity childEntity = childDtoMapper.fromDto(childDto);
someService.saveChild(parentEntityId, childEntity);
return ResponseEntity.created(...).build();
}
}
public class SomeServiceImpl {
@Autowired
private ParentEntityRepository parentEntityRepository;
@Autowired
private ChildEntityRepository childEntityRepository;
public ChildEntity saveChild(final long parentEntityId, final ChildEntity childEntity){
Optional<ParentEntity> parentEntity = parentEntityRepository.findById(parentEntityId);
if (parentEntity.isPresent()) {
childEntity.setParent(parentEntity.get());
childEntityRepository.save(childEntity);
return childEntity;
}
throw new EntityNotFoundException("Parent entity not found!");
}
}
Upvotes: 1
Views: 166
Reputation: 3393
I would choose the second option with the following modification:
@RestController
public class SomeController {
@Autowired
private SomeService someService;
@PostMapping("/parents/{parentEntityId}/childs")
public ResponseEntity<Void> save(@PathVariable("parentEntityId") Long parentEntityId, @RequestBody ChildDto childDto) {
someService.saveChild(parentEntityId, childDto);
return ResponseEntity.created(...).build();
}
}
public class SomeServiceImpl {
@Autowired
private ParentEntityRepository parentEntityRepository;
@Autowired
private ChildEntityRepository childEntityRepository;
public ChildEntity saveChild(final long parentEntityId, final ChildDto childDto){
ChildEntity childEntity = childDtoMapper.fromDto(childDto);
Optional<ParentEntity> parentEntity = parentEntityRepository.findById(parentEntityId);
if (parentEntity.isPresent()) {
childEntity.setParent(parentEntity.get());
childEntityRepository.save(childEntity);
return childEntity;
}
throw new EntityNotFoundException("Parent entity not found!");
}
}
Consider that in this way the controller has almost no logic: it simply forwards requests to the proper service, acting like a traffic controller. Also, using this approach, in some day in future you have to add some "alternative" controller, like a WebSocket or a old-style WebService, your effort for doing this would be minimal and you will minimize similarities between this controller and any future controller. The golden rule of this approach is the following: DAOs/Repository always returns Entities, Service always returns DTOs. Controllers are just interfaces for external world.
Upvotes: 4