Good morning I'm developing an application in which the user has to inform the system of a list of exams and the system to display the laboratory units that perform such exams, but I have a question about the way in which to record in the bank the examinations carried out by X drive all other data is already being stored as it should be stored.
This is the diagram template I developed for the application
DomainClasses/Entities
UnitLab.java
packagecom.moliveiralucas.easylab.domain;importjava.io.Serializable;importjava.util.ArrayList;importjava.util.List;importjavax.persistence.Entity;importjavax.persistence.GeneratedValue;importjavax.persistence.GenerationType;importjavax.persistence.Id;importjavax.persistence.JoinColumn;importjavax.persistence.JoinTable;importjavax.persistence.ManyToMany;importjavax.persistence.ManyToOne;importcom.fasterxml.jackson.annotation.JsonIgnore;@EntitypublicclassUnidadeLaboratorioimplementsSerializable{privatestaticfinallongserialVersionUID=1L;/*ATRIBUTOSBASICOS*/@Id@GeneratedValue(strategy=GenerationType.IDENTITY)privateIntegerid_UnidadeLaboratorio;privateStringnomeUnidade;privateStringlogradouro;privateStringcomplemento;privateStringnumero;privateStringtelefone;/*RELACIONAMENTOS*/@JsonIgnore@ManyToOne@JoinColumn(name="id_laboratorio")
private Laboratorio laboratorio;
@ManyToOne
@JoinColumn(name = "id_cidade")
private Cidade cidade;
@JsonIgnore
@ManyToMany
@JoinTable(name = "EXAMES_REALIZADOS", joinColumns = @JoinColumn(name = "id_unidade"), inverseJoinColumns = @JoinColumn(name = "id_exame"))
private List<Exame> exames = new ArrayList<>();
/* CONSTRUTORES */
public UnidadeLaboratorio() {
}
public UnidadeLaboratorio(Integer id_UnidadeLaboratorio, String nomeUnidade, String logradouro, String complemento,
String numero, String telefone, Cidade cidade, Laboratorio laboratorio) {
super();
this.id_UnidadeLaboratorio = id_UnidadeLaboratorio;
this.nomeUnidade = nomeUnidade;
this.logradouro = logradouro;
this.complemento = complemento;
this.numero = numero;
this.telefone = telefone;
this.cidade = cidade;
this.laboratorio = laboratorio;
}
/* GETTERS AND SETTERS */
public Integer getId_UnidadeLaboratorio() {
return id_UnidadeLaboratorio;
}
public void setId_UnidadeLaboratorio(Integer id_UnidadeLaboratorio) {
this.id_UnidadeLaboratorio = id_UnidadeLaboratorio;
}
public String getNomeUnidade() {
return nomeUnidade;
}
public void setNomeUnidade(String nomeUnidade) {
this.nomeUnidade = nomeUnidade;
}
public String getLogradouro() {
return logradouro;
}
public void setLogradouro(String logradouro) {
this.logradouro = logradouro;
}
public String getComplemento() {
return complemento;
}
public void setComplemento(String complemento) {
this.complemento = complemento;
}
public String getNumero() {
return numero;
}
public void setNumero(String numero) {
this.numero = numero;
}
public String getTelefone() {
return telefone;
}
public void setTelefone(String telefone) {
this.telefone = telefone;
}
public Cidade getCidade() {
return cidade;
}
public void setCidade(Cidade cidade) {
this.cidade = cidade;
}
public Laboratorio getLaboratorio() {
return laboratorio;
}
public void setLaboratorio(Laboratorio laboratorio) {
this.laboratorio = laboratorio;
}
public List<Exame> getExames() {
return exames;
}
public void setExames(List<Exame> exames) {
this.exames = exames;
}
/* HASHCODE AND EQUALS */
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id_UnidadeLaboratorio == null) ? 0 : id_UnidadeLaboratorio.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
UnidadeLaboratorio other = (UnidadeLaboratorio) obj;
if (id_UnidadeLaboratorio == null) {
if (other.id_UnidadeLaboratorio != null)
return false;
} else if (!id_UnidadeLaboratorio.equals(other.id_UnidadeLaboratorio))
return false;
return true;
}
}
Exam.java
package com.moliveiralucas.easylab.domain;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import com.fasterxml.jackson.annotation.JsonIgnore;
@Entity
public class Exame implements Serializable {
private static final long serialVersionUID = 1L;
/* ATRIBUTOS BASICOS */
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id_Exame;
private String exame;
private String sigla;
/* RELACIONAMENTOS */
@JsonIgnore
@ManyToMany(mappedBy = "exames")
private List<UnidadeLaboratorio> unidades = new ArrayList<>();
/* CONSTRUTORES */
public Exame() {
}
public Exame(Integer id_Exame, String exame, String sigla) {
super();
this.id_Exame = id_Exame;
this.exame = exame;
this.sigla = sigla;
}
/* GETTERS AND SETTERS */
public Integer getId_Exame() {
return id_Exame;
}
public void setId_Exame(Integer id_Exame) {
this.id_Exame = id_Exame;
}
public String getExame() {
return exame;
}
public void setExame(String exame) {
this.exame = exame;
}
public String getSigla() {
return sigla;
}
public void setSigla(String sigla) {
this.sigla = sigla;
}
public List<UnidadeLaboratorio> getUnidades() {
return unidades;
}
public void setUnidades(List<UnidadeLaboratorio> unidades) {
this.unidades = unidades;
}
/* HASHCODE AND EQUALS */
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id_Exame == null) ? 0 : id_Exame.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Exame other = (Exame) obj;
if (id_Exame == null) {
if (other.id_Exame != null)
return false;
} else if (!id_Exame.equals(other.id_Exame))
return false;
return true;
}
}
Data Transfer Object (DTO) Classes
UnitLaboratoryDTO.java
package com.moliveiralucas.easylab.dto;
import java.io.Serializable;
import javax.validation.constraints.NotEmpty;
import org.hibernate.validator.constraints.Length;
import com.moliveiralucas.easylab.domain.UnidadeLaboratorio;
public class UnidadeLaboratorioDTO implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id_UnidadeLaboratorio;
@NotEmpty(message = "Preenchimento obrigatório")
@Length(min = 3, max = 50, message = "O campo nomeUnidade deve conter entre 3 e 50 caracteres")
private String nomeUnidade;
@NotEmpty(message = "Preenchimento obrigatório")
@Length(min = 3, max = 50, message = "O campo Logradouro deve conter entre 3 e 50 caracteres")
private String logradouro;
@NotEmpty(message = "Preenchimento obrigatório")
@Length(min = 3, max = 50, message = "O campo Complemento deve conter entre 3 e 50 caracteres")
private String complemento;
private String numero;
private String telefone;
public UnidadeLaboratorioDTO() {
}
public UnidadeLaboratorioDTO(UnidadeLaboratorio obj) {
id_UnidadeLaboratorio = obj.getId_UnidadeLaboratorio();
nomeUnidade = obj.getNomeUnidade();
logradouro = obj.getLogradouro();
complemento = obj.getComplemento();
numero = obj.getNumero();
telefone = obj.getTelefone();
}
public Integer getId_UnidadeLaboratorio() {
return id_UnidadeLaboratorio;
}
public void setId_UnidadeLaboratorio(Integer id_UnidadeLaboratorio) {
this.id_UnidadeLaboratorio = id_UnidadeLaboratorio;
}
public String getNomeUnidade() {
return nomeUnidade;
}
public void setNomeUnidade(String nomeUnidade) {
this.nomeUnidade = nomeUnidade;
}
public String getLogradouro() {
return logradouro;
}
public void setLogradouro(String logradouro) {
this.logradouro = logradouro;
}
public String getComplemento() {
return complemento;
}
public void setComplemento(String complemento) {
this.complemento = complemento;
}
public String getNumero() {
return numero;
}
public void setNumero(String numero) {
this.numero = numero;
}
public String getTelefone() {
return telefone;
}
public void setTelefone(String telefone) {
this.telefone = telefone;
}
}
TestDTO.java
package com.moliveiralucas.easylab.dto;
import java.io.Serializable;
import javax.validation.constraints.NotEmpty;
import org.hibernate.validator.constraints.Length;
import com.moliveiralucas.easylab.domain.Exame;
public class ExameDTO implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id_Exame;
@NotEmpty(message = "Preenchimento obrigatório")
@Length(min = 3, max = 60, message = "O campo Exame deve ser entre 3 e 60 caracteres")
private String exame;
@NotEmpty(message = "Preenchimento obrigatório")
@Length(min = 2, max = 6, message = "O campo Sigla deve ser entre 3 e 6 caracteres")
private String sigla;
public ExameDTO() {
}
public ExameDTO(Exame obj) {
super();
id_Exame = obj.getId_Exame();
exame = obj.getExame();
sigla = obj.getSigla();
}
public Integer getId_Exame() {
return id_Exame;
}
public void setId_Exame(Integer id_Exame) {
this.id_Exame = id_Exame;
}
public String getExame() {
return exame;
}
public void setExame(String exame) {
this.exame = exame;
}
public String getSigla() {
return sigla;
}
public void setSigla(String sigla) {
this.sigla = sigla;
}
}
Repositories (JpaRepository)
Unity LabRepository.java
package com.moliveiralucas.easylab.repositories;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.moliveiralucas.easylab.domain.UnidadeLaboratorio;
@Repository
public interface UnidadeLaboratorioRepository extends JpaRepository<UnidadeLaboratorio, Integer> {
}
ExamRepository.java
package com.moliveiralucas.easylab.repositories;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.moliveiralucas.easylab.domain.Exame;
@Repository
public interface ExameRepository extends JpaRepository<Exame, Integer> {
/*
* @Transactional(readOnly=true)
*
* @Query("SELECT obj FROM exames_realizados obj WHERE obj.exame.id_exame = :exames.exame_id"
* ) List<Exame> findAllExames(ArrayList<Exame> exames);
*/
}
The comment commented out in the class ExameRepository.java and it popped an exception saying that "done_examples" was not mapped, so I was in doubt if I was to create a class to map this relationship or it was already being mapped in the domain classes. / p>
RestController classes
Laboratory UnitResouce.java
package com.moliveiralucas.easylab.resources;
import java.net.URI;
import java.util.List;
import java.util.stream.Collectors;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import com.moliveiralucas.easylab.domain.UnidadeLaboratorio;
import com.moliveiralucas.easylab.dto.UnidadeLaboratorioDTO;
import com.moliveiralucas.easylab.dto.UnidadeLaboratorioNewDTO;
import com.moliveiralucas.easylab.services.UnidadeLaboratorioService;
@RestController
@RequestMapping(value = "/unidadeLaboratorios")
public class UnidadeLaboratorioResource {
@Autowired
private UnidadeLaboratorioService service;
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public ResponseEntity<?> find(@PathVariable Integer id) {
UnidadeLaboratorio obj = service.find(id);
return ResponseEntity.ok().body(obj);
}
@RequestMapping(method = RequestMethod.GET)
public ResponseEntity<List<UnidadeLaboratorioDTO>> findAll() {
List<UnidadeLaboratorio> list = service.findAll();
List<UnidadeLaboratorioDTO> listDto = list.stream().map(obj -> new UnidadeLaboratorioDTO(obj))
.collect(Collectors.toList());
return ResponseEntity.ok().body(listDto);
}
@RequestMapping(value = "/page", method = RequestMethod.GET)
public ResponseEntity<Page<UnidadeLaboratorioDTO>> findPage( // page?page=XXX&linesPerPage=XXX&orderBy=XXX&direction=XXX
@RequestParam(value = "page", defaultValue = "0") Integer page,
@RequestParam(value = "linesPerPage", defaultValue = "24") Integer linesPerPage,
@RequestParam(value = "orderBy", defaultValue = "laboratorio") String orderBy,
@RequestParam(value = "direction", defaultValue = "ASC") String direction) {
Page<UnidadeLaboratorio> list = service.findPage(page, linesPerPage, orderBy, direction);
Page<UnidadeLaboratorioDTO> listDto = list.map(obj -> new UnidadeLaboratorioDTO(obj));
return ResponseEntity.ok().body(listDto);
}
@RequestMapping(method = RequestMethod.POST)
public ResponseEntity<Void> insert(@Valid @RequestBody UnidadeLaboratorioNewDTO objDto) {
UnidadeLaboratorio obj = service.fromNewDTO(objDto);
obj = service.insert(obj);
URI uri = ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}")
.buildAndExpand(obj.getId_UnidadeLaboratorio()).toUri();
return ResponseEntity.created(uri).build();
}
@RequestMapping(value = "/{id}", method = RequestMethod.PUT)
public ResponseEntity<Void> update(@PathVariable Integer id, @Valid @RequestBody UnidadeLaboratorioDTO objDto) {
UnidadeLaboratorio obj = service.fromDTO(objDto);
obj.setId_UnidadeLaboratorio(id);
obj = service.update(obj);
return ResponseEntity.noContent().build();
}
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
public ResponseEntity<Void> delete(@PathVariable Integer id) {
service.delete(id);
return ResponseEntity.noContent().build();
}
}
ExameResource.java
package com.moliveiralucas.easylab.resources;
import java.net.URI;
import java.util.List;
import java.util.stream.Collectors;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import com.moliveiralucas.easylab.domain.Exame;
import com.moliveiralucas.easylab.dto.ExameDTO;
import com.moliveiralucas.easylab.services.ExameService;
@RestController
@RequestMapping(value = "/exames")
public class ExameResource {
@Autowired
private ExameService service;
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public ResponseEntity<?> find(@PathVariable Integer id) {
Exame obj = service.find(id);
return ResponseEntity.ok().body(obj);
}
@RequestMapping(method = RequestMethod.GET)
public ResponseEntity<List<ExameDTO>> findAll() {
List<Exame> list = service.findAll();
List<ExameDTO> listDto = list.stream().map(obj -> new ExameDTO(obj)).collect(Collectors.toList());
return ResponseEntity.ok().body(listDto);
}
@RequestMapping(value = "/page", method = RequestMethod.GET)
public ResponseEntity<Page<ExameDTO>> findPage( // page?page=XXXX&linesPerPage=XXXX&orderBy=XXXX&direction=XXXX
@RequestParam(value = "page", defaultValue = "0") Integer page,
@RequestParam(value = "linesPerPage", defaultValue = "24") Integer linesPerPage,
@RequestParam(value = "orderBy", defaultValue = "exame") String orderBy,
@RequestParam(value = "direction", defaultValue = "ASC") String direction) {
Page<Exame> list = service.findPage(page, linesPerPage, orderBy, direction);
Page<ExameDTO> listDto = list.map(obj -> new ExameDTO(obj));
return ResponseEntity.ok().body(listDto);
}
@RequestMapping(method = RequestMethod.POST)
public ResponseEntity<Void> insert(@Valid @RequestBody ExameDTO objDto) {
Exame obj = service.fromDTO(objDto);
obj = service.insert(obj);
URI uri = ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(obj.getId_Exame())
.toUri();
return ResponseEntity.created(uri).build();
}
@RequestMapping(value = "/{id}", method = RequestMethod.PUT)
public ResponseEntity<Void> update(@PathVariable Integer id, @Valid @RequestBody ExameDTO objDto) {
Exame obj = service.fromDTO(objDto);
obj.setId_Exame(id);
obj = service.update(obj);
return ResponseEntity.noContent().build();
}
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
public ResponseEntity<Void> delete(@PathVariable Integer id) {
service.delete(id);
return ResponseEntity.noContent().build();
}
}
Service Classes
UnitLaboratoryService.java
package com.moliveiralucas.easylab.services;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.moliveiralucas.easylab.domain.Cidade;
import com.moliveiralucas.easylab.domain.Laboratorio;
import com.moliveiralucas.easylab.domain.UnidadeLaboratorio;
import com.moliveiralucas.easylab.dto.UnidadeLaboratorioDTO;
import com.moliveiralucas.easylab.dto.UnidadeLaboratorioNewDTO;
import com.moliveiralucas.easylab.repositories.UnidadeLaboratorioRepository;
import com.moliveiralucas.easylab.services.exceptions.DataIntegrityException;
import com.moliveiralucas.easylab.services.exceptions.ObjectNotFoundException;
@Service
public class UnidadeLaboratorioService {
@Autowired
private UnidadeLaboratorioRepository repo;
public UnidadeLaboratorio find(Integer id) {
Optional<UnidadeLaboratorio> obj = repo.findById(id);
return obj.orElseThrow(() -> new ObjectNotFoundException(
"Objeto não encontrado! ID: " + id + ", Tipo: " + UnidadeLaboratorio.class.getName()));
}
public List<UnidadeLaboratorio> findAll() {
return repo.findAll();
}
public Page<UnidadeLaboratorio> findPage(Integer page, Integer linesPerPage, String orderBy, String direction) {
PageRequest pageRequest = PageRequest.of(page, linesPerPage, Direction.valueOf(direction), orderBy);
return repo.findAll(pageRequest);
}
@Transactional
public UnidadeLaboratorio insert(UnidadeLaboratorio obj) {
obj.setId_UnidadeLaboratorio(null);
return repo.save(obj);
}
public UnidadeLaboratorio update(UnidadeLaboratorio obj) {
UnidadeLaboratorio newObj = find(obj.getId_UnidadeLaboratorio());
updateData(newObj, obj);
return repo.save(newObj);
}
private void updateData(UnidadeLaboratorio newObj, UnidadeLaboratorio obj) {
newObj.setNomeUnidade(obj.getNomeUnidade());
newObj.setLogradouro(obj.getLogradouro());
newObj.setComplemento(obj.getComplemento());
newObj.setNumero(obj.getNumero());
newObj.setTelefone(obj.getTelefone());
}
public void delete(Integer id) {
find(id);
try {
repo.deleteById(id);
} catch (DataIntegrityViolationException e) {
throw new DataIntegrityException("Não é possível excluir!");
}
}
public UnidadeLaboratorio fromDTO(UnidadeLaboratorioDTO objDto) {
return new UnidadeLaboratorio(objDto.getId_UnidadeLaboratorio(), objDto.getNomeUnidade(),
objDto.getLogradouro(), objDto.getComplemento(), objDto.getNumero(), objDto.getTelefone(), null, null);
}
public UnidadeLaboratorio fromNewDTO(UnidadeLaboratorioNewDTO objDto) {
Laboratorio laboratorio = new Laboratorio(objDto.getId_Laboratorio(), null, null, null);
Cidade cidade = new Cidade(objDto.getId_Cidade(), null, null);
UnidadeLaboratorio unidadeLaboratorio = new UnidadeLaboratorio(null, objDto.getNomeUnidade(),
objDto.getLogradouro(), objDto.getComplemento(), objDto.getNumero(), objDto.getTelefone(), cidade,
laboratorio);
laboratorio.getUnidades().add(unidadeLaboratorio);
return unidadeLaboratorio;
}
}
ExameService.java
package com.moliveiralucas.easylab.services;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Service;
import com.moliveiralucas.easylab.domain.Exame;
import com.moliveiralucas.easylab.dto.ExameDTO;
import com.moliveiralucas.easylab.repositories.ExameRepository;
import com.moliveiralucas.easylab.services.exceptions.DataIntegrityException;
import com.moliveiralucas.easylab.services.exceptions.ObjectNotFoundException;
@Service
public class ExameService {
@Autowired
private ExameRepository repo;
public Exame find(Integer id) {
Optional<Exame> obj = repo.findById(id);
return obj.orElseThrow(() -> new ObjectNotFoundException(
"Objeto não encontrado! ID: " + id + ", Tipo: " + Exame.class.getName()));
}
public List<Exame> findAll() {
return repo.findAll();
}
public Page<Exame> findPage(Integer page, Integer linesPerPage, String orderBy, String direction) {
PageRequest pageRequest = PageRequest.of(page, linesPerPage, Direction.valueOf(direction), orderBy);
return repo.findAll(pageRequest);
}
public Exame insert(Exame obj) {
obj.setId_Exame(null);
return repo.save(obj);
}
public Exame update(Exame obj) {
Exame newObj = find(obj.getId_Exame());
updateData(newObj, obj);
return repo.save(newObj);
}
private void updateData(Exame newObj, Exame obj) {
newObj.setExame(obj.getExame());
newObj.setSigla(obj.getSigla());
}
public void delete(Integer id) {
find(id);
try {
repo.deleteById(id);
} catch (DataIntegrityViolationException e) {
throw new DataIntegrityException("Não é possível excluir!");
}
}
public Exame fromDTO(ExameDTO objDto) {
return new Exame(objDto.getId_Exame(), objDto.getExame(), objDto.getSigla());
}
}
These are the classes I'm using to keep the exams and the units, the one my question is, should I create a new class to maintain / map this relationship between the Lab unit and the exam so that I can manipulate the data in it or I should only make a responsible method for such a thing.
The repository in which the entire project is stored is: Github
From now thank you for the collaboration of everyone :)