As you can see, he is returning cities without any problems at the following URL: http://localhost:8080/cidades
, please note:
Thisisadirectreturnfromthedatabasewithselect*fromcidade
,canyouseeanydifference?
Notethatinthestatus_codeattributeappearsintheSQLperformedinthedatabase,butthesameattributedoesnotappearinthelistmadebytheSpringBootJavaAPI,asIwouldalsoliketheattributewouldalsobereturnedinJavaAPIJson.
HowdoIgettheAPItoreturnthisattribute?
HerebelowarethecodesrespondingtothelistreturnedbytheURL:http://localhost:8080/cidades
Thecontroller:
packagecom.algaworks.brewer.resource;importjava.util.List;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RestController;importcom.algaworks.brewer.model.Cidade;importcom.algaworks.brewer.model.Estado;importcom.algaworks.brewer.repository.CidadeRepository;importcom.algaworks.brewer.repository.EstadoRepository;importcom.algaworks.brewer.repository.filter.CidadeFilter;@RestController@RequestMapping("/cidades")
public class CidadeResource {
@Autowired
private CidadeRepository cidadeRepository;
@Autowired
private EstadoRepository estadoRepository;
@GetMapping
public List<Cidade> pesquisarPorCidade(CidadeFilter cidadeFilter){
return cidadeRepository.filtrar(cidadeFilter);
}
@GetMapping("/estados")
public List<Estado> pesquisarPorEstado(){
return estadoRepository.findAll();
}
}
The repository :
package com.algaworks.brewer.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.algaworks.brewer.model.Cidade;
import com.algaworks.brewer.repository.cidade.CidadeRepositoryQuery;
public interface CidadeRepository extends JpaRepository<Cidade, Long> , CidadeRepositoryQuery {
}
The filter implementation interface:
package com.algaworks.brewer.repository.cidade;
import java.util.List;
import com.algaworks.brewer.model.Cidade;
import com.algaworks.brewer.repository.filter.CidadeFilter;
public interface CidadeRepositoryQuery {
public List<Cidade> filtrar(CidadeFilter cidadeFilter);
}
The implementation itself:
package com.algaworks.brewer.repository.cidade;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.springframework.util.StringUtils;
import com.algaworks.brewer.model.Cidade;
import com.algaworks.brewer.model.Cidade_;
import com.algaworks.brewer.repository.filter.CidadeFilter;
public class CidadeRepositoryImpl implements CidadeRepositoryQuery {
@PersistenceContext
private EntityManager manager;
@Override
public List<Cidade> filtrar(CidadeFilter cidadeFilter) {
CriteriaBuilder builder = manager.getCriteriaBuilder();
CriteriaQuery<Cidade> criteria = builder.createQuery(Cidade.class);
Root<Cidade> root = criteria.from(Cidade.class);
Predicate[] predicates = criarRestricoes(cidadeFilter, builder, root);
criteria.where(predicates);
TypedQuery<Cidade> query = manager.createQuery(criteria);
return query.getResultList();
}
private Predicate[] criarRestricoes(CidadeFilter cidadeFilter, CriteriaBuilder builder,
Root<Cidade> root) {
List<Predicate> predicates = new ArrayList<>();
if (!StringUtils.isEmpty(cidadeFilter.getNome())) {
predicates.add(builder.like(
builder.lower(root.get(Cidade_.nome)), "%" + cidadeFilter.getNome().toLowerCase() + "%"));
}
return predicates.toArray(new Predicate[predicates.size()]);
}
}
//if (cidadeFilter.getEstado() != null) {
// predicates.add(
// builder.greaterThanOrEqualTo(root.get(Cidade_.estado.getName()), cidadeFilter.getEstado().getNome()));
//}
I'm looking forward to the return!
This is the city code:
package com.algaworks.brewer.model;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.NotBlank;
import com.fasterxml.jackson.annotation.JsonIgnore;
@Entity
@Table(name = "cidade")
public class Cidade implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long codigo;
@NotBlank(message = "Nome é obrigatório")
private String nome;
@NotNull(message = "Estado é obrigatório")
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "codigo_estado")
@JsonIgnore
private Estado estado;
public Long getCodigo() {
return codigo;
}
public void setCodigo(Long codigo) {
this.codigo = codigo;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public Estado getEstado() {
return estado;
}
public void setEstado(Estado estado) {
this.estado = estado;
}
public boolean temEstado() {
return estado != null;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((codigo == null) ? 0 : codigo.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;
Cidade other = (Cidade) obj;
if (codigo == null) {
if (other.codigo != null)
return false;
} else if (!codigo.equals(other.codigo))
return false;
return true;
}
}
And from the entity State:
package com.algaworks.brewer.model;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "estado")
public class Estado implements Serializable {
private static final long serialVersionUID = 1L;
private Long codigo;
private String nome;
private String sigla;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Long getCodigo() {
return codigo;
}
public void setCodigo(Long codigo) {
this.codigo = codigo;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getSigla() {
return sigla;
}
public void setSigla(String sigla) {
this.sigla = sigla;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((codigo == null) ? 0 : codigo.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;
Estado other = (Estado) obj;
if (codigo == null) {
if (other.codigo != null)
return false;
} else if (!codigo.equals(other.codigo))
return false;
return true;
}
}
You may notice that there is a @JsonIgnore
in private Estado estado
it's being ignored, I took that code from somewhere else that's why it's there, I need to make a changeover time so that LAZY
still works.
see the excerpt:
@NotNull(message = "Estado é obrigatório")
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "codigo_estado")
@JsonIgnore
private Estado estado;