java.lang.stackOverFlowError no SpringBoot Java

Oi pessoal,
O spring carrega o programa normalmente e as tabelas do H2 são criadas e preenchidas corretamente, porém quando eu tento consumir a api com GET ocorre o estouro de pilha.
Apliquei o @JsonIgnore em TODOS os mapeamentos jpa pois estava achando que se tratava de referência cíclica mas o resultado no postman foi o mesmo abaixo:

"timestamp": "2020-05-07T22:47:35.243+0000",
"status": 500,
"error": "Internal Server Error",
"message": "No message available",
"trace": "java.lang.StackOverflowError\r\n\tat org.hibernate.loader.plan.build.internal.returns.AbstractExpandingFetchSource.getFetches(AbstractExpandingFetchSource.java:75)\r\n\tat org.hibernate.loader.plan.build.internal.returns.AbstractCompositeEntityIdentifierDescription.hasFetches(AbstractCompositeEntityIdentifierDescription.java:40)\r\n\tat org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.resolveEntityKey(AbstractRowReader.java:146)\r\n\tat org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.resolveEntityKey(AbstractRowReader.java:147)\r\n\tat",

                  "erro repete várias vezes",

“org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.resolveEntityKey(AbstractRowReader.java:161)\r\n”,
“path”: “/passageiros/1”,

Console do spring após a requisição:

“at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.resolveEntityKey(AbstractRowReader.java:161) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.resolveEntityKey(AbstractRowReader.java:147) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.resolveEntityKey(AbstractRowReader.java:161) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.resolveEntityKey(AbstractRowReader.java:147) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]”

CONTINUA REPETINDO…

"at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.resolveEntityKey(AbstractRowReader.java:147) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.resolveEntityKey(AbstractRowReader.java:161) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.resolveEntityKey(AbstractRowReader.java:147) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]

2020-05-07 20:39:17.298 DEBUG 32132 — [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : “ERROR” dispatch for GET “/error”, parameters={}
2020-05-07 20:39:17.305 DEBUG 32132 — [nio-8081-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest)
2020-05-07 20:39:17.443 DEBUG 32132 — [nio-8081-exec-1] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Using ‘application/json’, given [/] and supported [application/json, application/+json, application/json, application/+json]
2020-05-07 20:39:17.445 DEBUG 32132 — [nio-8081-exec-1] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Writing [{timestamp=Thu May 07 20:39:17 BRT 2020, status=500, error=Internal Server Error, message=No message (truncated)…]
2020-05-07 20:39:17.648 DEBUG 32132 — [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Exiting from “ERROR” dispatch, status 500"

@samuelfranck

só lendo o log não da para saber o que é mas o que causou, o que parece ser um loop infinito.

caso queira uma ajuda melhor post o código da rota “/passageiros/1”

1 curtida

Ok @Villagram O que seria a rota? seria repository, service e resource da classe Passageiro?

Obrigado

o código do controller e o service.

Boa noite @Villagram

Segue os códigos

package com.samuelfranck.companhiaaerea.resources;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.samuelfranck.companhiaaerea.domain.Passageiro;
import com.samuelfranck.companhiaaerea.services.PassageiroService;

@RestController
@RequestMapping(value="/passageiros")
public class PassageiroResource {

@Autowired
private PassageiroService service;

@RequestMapping(value="/{id}", method=RequestMethod.GET)
public ResponseEntity<?> find(@PathVariable Integer id) {
	Passageiro obj = service.find(id);
	return ResponseEntity.ok().body(obj);
}

package com.samuelfranck.companhiaaerea.services;

import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.samuelfranck.companhiaaerea.domain.Passageiro;
import com.samuelfranck.companhiaaerea.repositories.PassageiroRepository;
import com.samuelfranck.companhiaaerea.services.exceptions.ObjectNotFoundException;

@Service
public class PassageiroService {

@Autowired
private PassageiroRepository repo;

public Passageiro find(Integer id){
	Optional<Passageiro> obj = repo.findById(id);
	return obj.orElseThrow(() -> new ObjectNotFoundException("Objeto não encontrado! Id: "
	+ id +" Tipo: "+ Passageiro.class.getName()));`
package com.samuelfranck.companhiaaerea.domain;

import java.io.Serializable;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CollectionTable;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.MapsId;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;

import com.fasterxml.jackson.annotation.JsonFormat;

@Entity
public class Passageiro implements Serializable {
private static final long serialVersionUID = 1L;

@Id
private Integer id;

@JsonFormat(pattern = "dd/MM/yyyy")
private Date dataNascimento;

@JoinColumn(name = "pessoa_id")
@OneToOne
@MapsId
private Pessoa pessoa;

@ElementCollection
@CollectionTable(name = "TELEFONE")
private Set<String> telefones = new HashSet<>();

@OneToMany(mappedBy = "id.passageiro")
private Set<Reserva> reservas = new HashSet<>();

public Passageiro() {
}

public Passageiro(Integer id, Date dataNascimento, Pessoa pessoa) {
	super();
	this.id = id;
	this.dataNascimento = dataNascimento;
	this.pessoa = pessoa;
}

public Integer getId() {
	return id;
}

public void setId(Integer id) {
	this.id = id;
}

public Date getDataNascimento() {
	return dataNascimento;
}

public void setDataNascimento(Date dataNascimento) {
	this.dataNascimento = dataNascimento;
}

public Pessoa getPessoa() {
	return pessoa;
}

public void setPessoa(Pessoa pessoa) {
	this.pessoa = pessoa;
}

public Set<String> getTelefones() {
	return telefones;
}

public void setTelefones(Set<String> telefones) {
	this.telefones = telefones;
}

public Set<Reserva> getReservas() {
	return reservas;
}

public void setReservas(Set<Reserva> reservas) {
	this.reservas = reservas;
}

@Override
public int hashCode() {
	final int prime = 31;
	int result = 1;
	result = prime * result + ((id == null) ? 0 : id.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;
	Passageiro other = (Passageiro) obj;
	if (id == null) {
		if (other.id != null)
			return false;
	} else if (!id.equals(other.id))
		return false;
	return true;
}

}

Boa noite, acho que o seu problema pode estar no controller mesmo, segue:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/passageiros")
public class PassageiroResource {

    @Autowired
    private PassageiroService service;

    @GetMapping("/{id}")
    public ResponseEntity<Passageiro> find(@PathVariable("id") Integer id) {
        Passageiro obj = service.find(id);
        return ResponseEntity.ok().body(obj);
    }

}

@Villagram muito obrigado pela resposta.
Eu fiz as alterações e o resultado foi o mesmo.

Bom dia

Minha segunda suspeita está nesse trecho de código:

@ElementCollection
@CollectionTable(name = "TELEFONE")
private Set<String> telefones = new HashSet<>();

Essa tabela de telefones têm muitos dados?
Pois você está pegando ela toda sem nenhum critério.

@Villagram são apenas dois telefones para cada passageiro.
Poderia ser algum erro no mapeamento JPA? Estou utlizando uma classe de associação com atributos
embutidos e essa foi uma característica que me gerou algumas dúvidas.

bom dia, esse recurso do jpa pega uma tabela sem relação explicita e coloca pra uso usando as regras que você coloca dentro relacionamento. Nesse caso não tem regra nenhuma, então ele está puxando toda a tabela para cada registro dentro da tabela de passageiros, por esse motivo está dando essa exception.

@samuelfranck
Esse é um exemplo de algo que uso no dia a dia, eu tenho uma tabela que registro os ids dos atestado mas não tem relação explicita no banco, então uso o ElementCollection para que o id registrado na tabela e pegar os dados de atestado em outra tabela.

    @ElementCollection
    @Column(name = "ATESTADO")
    @CollectionTable(name = "MOV_ATESTADO", joinColumns = @JoinColumn(name = "NUMERO_GUIA"))
    private List<Long> atestados;

Quando chegar em casa vou remover este trecho do código pra ver o que acontece.

Obrigado.