2
As you can see it is returning to the cities without any problems in the following URL: http://localhost:8080/cidades
, watch:
This is a return coming straight from the database with a select * from cidade
, you can see some difference?
They realize that in the attribute status code appears in the SQL performed in the database, but this same attribute does not appear in the list made by the Java API of Spring Boot, as it would also like the attribute status code was also returned in the Json of the Java API.
How do I get the API to achieve returns this attribute?
Here below are the responding codes the list returned by the URL: http://localhost:8080/cidades
The controller:
package com.algaworks.brewer.resource;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.algaworks.brewer.model.Cidade;
import com.algaworks.brewer.model.Estado;
import com.algaworks.brewer.repository.CidadeRepository;
import com.algaworks.brewer.repository.EstadoRepository;
import com.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 look forward to the return!
That’s 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 the State entity:
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 can see that there is one @JsonIgnore
in the private Estado estado
it’s like being ignored, I took this code from somewhere else that’s why it’s there, I need to make a change time in such a way that the LAZY
still work.
see the excerpt:
@NotNull(message = "Estado é obrigatório")
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "codigo_estado")
@JsonIgnore
private Estado estado;
You can post your entity code
Cidade
? I think you should be mappingEstado
in a relationship@ManyToOne
(which is correct in JPA). To do what you want you will probably have to create a new fieldcodigoEstado
with the annotation@Column(name="codigo_estado", updatable=false, insertable=false)
but this is not the best of ideas (in practice the relational model is "leaking" to higher layers of application)– Anthony Accioly
@wladyband Post to us its entities. It would be of great value to evaluate how are the relationships and mappings.
– Tássio Auad
@Youngerauad , I just updated the post by putting the code of the two entities, could you take a look at me please?
– wladyband
@Anthonyaccioly take a look please? I updated the post
– wladyband
@wladyband, try my suggestion from the above comment:
@Column(name="codigo_estado", updatable=false, insertable=false) private Long codigoEstado;
in practice but perhaps it is better to create a different object for the service and copy the necessary values of City and State.– Anthony Accioly