Suppose I have a simple application with entities like these:
Dog.java:
@Entity(name = "dogs")
public class Dog {
@Id
@SequenceGenerator(name = "dog_sequence",
sequenceName = "dog_sequence",
allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE,
generator = "dog_sequence")
private Long id;
@Column(unique = true)
private String name;
// getters, setters, constructors
}
Command.java:
@Entity(name = "commands")
public class Command {
@Id
@SequenceGenerator(name = "command_sequence",
sequenceName = "command_sequence",
allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE,
generator = "command_sequence")
private Long id;
@Column(unique = true)
private String name;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "dog_id", nullable = false)
private Dog dog;
// getters, setters, constructors
}
So a dog can know several commands, and each command is unique for a dog (belongs only to one dog).
I have a view (website page) that allows the admin to add new commands to each dog and also change the dog's name.
Once done, the view would send a POST
request to /api/dog/edit
with JSON like this:
{
"commands": ["some command name", "another command name"],
"id": 1,
"name": "Updated Dog Name"
}
Now, because the Dog
entity doesn't contain a List<Command>
field, the controller can't map all of the JSON to the Dog
entity, so I created a DogDto
:
DogDto.java:
public class DogDto {
private Long id;
private String name;
private List<CommandDto> commands;
// getters, setters, constructors
}
and CommandDto
:
CommandDto.java:
public class CommandDto {
private Long id;
private String name;
private DogDto dog;
// getters, setters, constructors
}
Now my controller can map the JSON passed from view to the DogDto
:
@RestController
@RequestMapping(path = "api/dog")
public class DogController {
...
@PostMapping("edit")
@CrossOrigin
public ResponseEntity<DogDto> editDog(@RequestBody DogDto dogDto) {
...
Dog dog = mapper.map(dogDto, Dog.class);
List<Command> commands = new ArrayList<>();
for (CommandDto commandDto: dogDto.getCommands()) {
Command command = mapper.map(commandDto, Command.class);
commands.add(command);
}
...
}
}
Now I can map the DogDto
to a Dog
and Command
entities. But what would be the best way to persist them? Currently my DogService
has a
public boolean editDog(Dog dog) {...}
method that accepts a dog, tries to find it by ID:
Dog foundDog = this.dogRepository.findById(dog.getId());
and if the dog was found, update its name field and do this.dogRepository.save(foundDog);
.
However I also need to save the commands. The Dog
entity doesn't contain the list of commands. So I either need to change the editDog
method signature to boolean editDog(DogDto dog)
or do it in the controller like this:
for (Command command: commands) {
command.setDog(dogFoundById);
this.commandService.createCommand(command);
}
I'm lost as to what to do here.
And I've also been wondering what if I had a more complex structure, with more nested entities:
public class A {
...
@OneToMany
private List<B> bs;
}
public class C {
...
@ManyToOne
private B b;
}
would the best design decision be different?
Aucun commentaire:
Enregistrer un commentaire