skip to Main Content

I have been asking something similar in this question Link, but the answer did not resolve the problem.

  • I saw a tutorial for handling circular references here the post.

  • I applied those and the other ones, but no ones working and it shows the same error.

  • I’ve already try putting @JsonManagedReference and @JsonBackReference. At the class and at the attribute, but it didn’t work too.

  • I’ve already try putting @JsonIgnore, but it didn’t work too.

  • I’ve already try putting fetch: Lazy and Eager, but it didn’t work too.

  • I don’t want to create DTO or use mapper. Because de solution have to be simple. It’s a tutorial that I have to follow like that.

Following the my code here:

Departamento class:

package br.com.camila.projetoempresa.model;

import java.util.List;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;

@Entity
@Table(name="departamento")
public class Departamento {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="numero_id")
    private Integer numeroId;
    
    @Column(name="nome", nullable = false, length = 100)    
    private String nome;
    
    @Column(name="andar", nullable = false)
    private Integer andar;
    
    @OneToMany(mappedBy = "depto", cascade = CascadeType.ALL)   
    @JsonIgnoreProperties("depto")
    private List<Funcionario> listaFuncionarios;

    public Integer getNumeroId() {
        return numeroId;
    }

    public void setNumeroId(Integer numeroId) {
        this.numeroId = numeroId;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public Integer getAndar() {
        return andar;
    }

    public void setAndar(Integer andar) {
        this.andar = andar;
    }

    public List<Funcionario> getListaFuncionarios() {
        return listaFuncionarios;
    }

    public void setListaFuncionarios(List<Funcionario> listaFuncionarios) {
        this.listaFuncionarios = listaFuncionarios;
    }
    
}

Funcionario class:

package br.com.camila.projetoempresa.model;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;

@Entity
@Table(name="funcionario")
public class Funcionario {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "num_funcional", nullable = false)
    private Integer numFuncional;
    
    @Column(name="nome", nullable = false, length = 100)    
    private String nome;
    
    @Column(name="email", nullable = false, length = 100, unique = true)
    private String email;
    
    @Column(name="salario")
    private Double salario;
    
    @ManyToOne
    @JoinColumn(name="numero_id")
    @JsonIgnoreProperties("listaFuncionarios")  
    private Departamento depto;

    public Integer getNumFuncional() {
        return numFuncional;
    }

    public void setNumFuncional(Integer numFuncional) {
        this.numFuncional = numFuncional;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Double getSalario() {
        return salario;
    }

    public void setSalario(Double salario) {
        this.salario = salario;
    }

    public Departamento getDepartamento() {
        return depto;
    }

    public void setDepartamento(Departamento departamento) {
        this.depto = departamento;
    }   
    
}

DepartamentoController:

package br.com.camila.projetoempresa.controller;

import java.util.ArrayList;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import br.com.camila.projetoempresa.dao.DepartamentoDAO;
import br.com.camila.projetoempresa.model.Departamento;

@RestController
public class DepartamentoController {
    
    @Autowired
    private DepartamentoDAO dao;
    
    @GetMapping("/departamentos")
    public ArrayList<Departamento> recuperarTodos(){
        ArrayList<Departamento> departamentos;
        departamentos = (ArrayList<Departamento>)dao.findAll();
        return departamentos;
    }

}

FuncionarioController:

package br.com.camila.projetoempresa.controller;

import java.util.ArrayList;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import br.com.camila.projetoempresa.dao.FuncionarioDAO;
import br.com.camila.projetoempresa.model.Funcionario;

@RestController
public class FuncionarioController {
    
    @Autowired
    private FuncionarioDAO dao;
    
    @GetMapping("/testefuncionario")
    public Funcionario recuperarTeste() {
        Funcionario teste = dao.findById(1).get();
        return teste;
    }
    
    @GetMapping("/todos")
    public ArrayList<Funcionario> recuperarTodos(){     
        return (ArrayList<Funcionario>)dao.findAll();
    }

}

Console from STS:

2024-08-04T20:48:20.846-03:00[0;39m [32m INFO[0;39m [35m23136[0;39m [2m---[0;39m [2m[projetoempresa] [  restartedMain][0;39m [2m[0;39m[36mb.c.c.p.ProjetoempresaApplication       [0;39m [2m:[0;39m Starting ProjetoempresaApplication using Java 17.0.8 with PID 23136 (C:UsersCamilaOneDriveGitHubprojetoempresatargetclasses started by Camila in C:UsersCamilaOneDriveGitHubprojetoempresa)
[2m2024-08-04T20:48:20.849-03:00[0;39m [32m INFO[0;39m [35m23136[0;39m [2m---[0;39m [2m[projetoempresa] [  restartedMain][0;39m [2m[0;39m[36mb.c.c.p.ProjetoempresaApplication       [0;39m [2m:[0;39m No active profile set, falling back to 1 default profile: "default"
[2m2024-08-04T20:48:20.910-03:00[0;39m [32m INFO[0;39m [35m23136[0;39m [2m---[0;39m [2m[projetoempresa] [  restartedMain][0;39m [2m[0;39m[36m.e.DevToolsPropertyDefaultsPostProcessor[0;39m [2m:[0;39m Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
[2m2024-08-04T20:48:20.910-03:00[0;39m [32m INFO[0;39m [35m23136[0;39m [2m---[0;39m [2m[projetoempresa] [  restartedMain][0;39m [2m[0;39m[36m.e.DevToolsPropertyDefaultsPostProcessor[0;39m [2m:[0;39m For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
[2m2024-08-04T20:48:21.593-03:00[0;39m [32m INFO[0;39m [35m23136[0;39m [2m---[0;39m [2m[projetoempresa] [  restartedMain][0;39m [2m[0;39m[36m.s.d.r.c.RepositoryConfigurationDelegate[0;39m [2m:[0;39m Bootstrapping Spring Data JPA repositories in DEFAULT mode.
[2m2024-08-04T20:48:21.659-03:00[0;39m [32m INFO[0;39m [35m23136[0;39m [2m---[0;39m [2m[projetoempresa] [  restartedMain][0;39m [2m[0;39m[36m.s.d.r.c.RepositoryConfigurationDelegate[0;39m [2m:[0;39m Finished Spring Data repository scanning in 57 ms. Found 2 JPA repository interfaces.
[2m2024-08-04T20:48:22.207-03:00[0;39m [32m INFO[0;39m [35m23136[0;39m [2m---[0;39m [2m[projetoempresa] [  restartedMain][0;39m [2m[0;39m[36mo.s.b.w.embedded.tomcat.TomcatWebServer [0;39m [2m:[0;39m Tomcat initialized with port 8080 (http)
[2m2024-08-04T20:48:22.219-03:00[0;39m [32m INFO[0;39m [35m23136[0;39m [2m---[0;39m [2m[projetoempresa] [  restartedMain][0;39m [2m[0;39m[36mo.apache.catalina.core.StandardService  [0;39m [2m:[0;39m Starting service [Tomcat]
[2m2024-08-04T20:48:22.220-03:00[0;39m [32m INFO[0;39m [35m23136[0;39m [2m---[0;39m [2m[projetoempresa] [  restartedMain][0;39m [2m[0;39m[36mo.apache.catalina.core.StandardEngine   [0;39m [2m:[0;39m Starting Servlet engine: [Apache Tomcat/10.1.26]
[2m2024-08-04T20:48:22.279-03:00[0;39m [32m INFO[0;39m [35m23136[0;39m [2m---[0;39m [2m[projetoempresa] [  restartedMain][0;39m [2m[0;39m[36mo.a.c.c.C.[Tomcat].[localhost].[/]      [0;39m [2m:[0;39m Initializing Spring embedded WebApplicationContext
[2m2024-08-04T20:48:22.279-03:00[0;39m [32m INFO[0;39m [35m23136[0;39m [2m---[0;39m [2m[projetoempresa] [  restartedMain][0;39m [2m[0;39m[36mw.s.c.ServletWebServerApplicationContext[0;39m [2m:[0;39m Root WebApplicationContext: initialization completed in 1368 ms
[2m2024-08-04T20:48:22.411-03:00[0;39m [32m INFO[0;39m [35m23136[0;39m [2m---[0;39m [2m[projetoempresa] [  restartedMain][0;39m [2m[0;39m[36mcom.zaxxer.hikari.HikariDataSource      [0;39m [2m:[0;39m HikariPool-1 - Starting...
[2m2024-08-04T20:48:22.710-03:00[0;39m [32m INFO[0;39m [35m23136[0;39m [2m---[0;39m [2m[projetoempresa] [  restartedMain][0;39m [2m[0;39m[36mcom.zaxxer.hikari.pool.HikariPool       [0;39m [2m:[0;39m HikariPool-1 - Added connection com.mysql.cj.jdbc.ConnectionImpl@13082f92
[2m2024-08-04T20:48:22.713-03:00[0;39m [32m INFO[0;39m [35m23136[0;39m [2m---[0;39m [2m[projetoempresa] [  restartedMain][0;39m [2m[0;39m[36mcom.zaxxer.hikari.HikariDataSource      [0;39m [2m:[0;39m HikariPool-1 - Start completed.
[2m2024-08-04T20:48:22.768-03:00[0;39m [32m INFO[0;39m [35m23136[0;39m [2m---[0;39m [2m[projetoempresa] [  restartedMain][0;39m [2m[0;39m[36mo.hibernate.jpa.internal.util.LogHelper [0;39m [2m:[0;39m HHH000204: Processing PersistenceUnitInfo [name: default]
[2m2024-08-04T20:48:22.834-03:00[0;39m [32m INFO[0;39m [35m23136[0;39m [2m---[0;39m [2m[projetoempresa] [  restartedMain][0;39m [2m[0;39m[36morg.hibernate.Version                   [0;39m [2m:[0;39m HHH000412: Hibernate ORM core version 6.5.2.Final
[2m2024-08-04T20:48:22.877-03:00[0;39m [32m INFO[0;39m [35m23136[0;39m [2m---[0;39m [2m[projetoempresa] [  restartedMain][0;39m [2m[0;39m[36mo.h.c.internal.RegionFactoryInitiator   [0;39m [2m:[0;39m HHH000026: Second-level cache disabled
[2m2024-08-04T20:48:23.258-03:00[0;39m [32m INFO[0;39m [35m23136[0;39m [2m---[0;39m [2m[projetoempresa] [  restartedMain][0;39m [2m[0;39m[36mo.s.o.j.p.SpringPersistenceUnitInfo     [0;39m [2m:[0;39m No LoadTimeWeaver setup: ignoring JPA class transformer
[2m2024-08-04T20:48:23.340-03:00[0;39m [33m WARN[0;39m [35m23136[0;39m [2m---[0;39m [2m[projetoempresa] [  restartedMain][0;39m [2m[0;39m[36morg.hibernate.orm.deprecation           [0;39m [2m:[0;39m HHH90000025: MySQLDialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
[2m2024-08-04T20:48:24.278-03:00[0;39m [32m INFO[0;39m [35m23136[0;39m [2m---[0;39m [2m[projetoempresa] [  restartedMain][0;39m [2m[0;39m[36mo.h.e.t.j.p.i.JtaPlatformInitiator      [0;39m [2m:[0;39m HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
[2m2024-08-04T20:48:24.281-03:00[0;39m [32m INFO[0;39m [35m23136[0;39m [2m---[0;39m [2m[projetoempresa] [  restartedMain][0;39m [2m[0;39m[36mj.LocalContainerEntityManagerFactoryBean[0;39m [2m:[0;39m Initialized JPA EntityManagerFactory for persistence unit 'default'
[2m2024-08-04T20:48:24.643-03:00[0;39m [33m WARN[0;39m [35m23136[0;39m [2m---[0;39m [2m[projetoempresa] [  restartedMain][0;39m [2m[0;39m[36mJpaBaseConfiguration$JpaWebConfiguration[0;39m [2m:[0;39m spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
[2m2024-08-04T20:48:24.986-03:00[0;39m [32m INFO[0;39m [35m23136[0;39m [2m---[0;39m [2m[projetoempresa] [  restartedMain][0;39m [2m[0;39m[36mo.s.b.d.a.OptionalLiveReloadServer      [0;39m [2m:[0;39m LiveReload server is running on port 35729
[2m2024-08-04T20:48:25.027-03:00[0;39m [32m INFO[0;39m [35m23136[0;39m [2m---[0;39m [2m[projetoempresa] [  restartedMain][0;39m [2m[0;39m[36mo.s.b.w.embedded.tomcat.TomcatWebServer [0;39m [2m:[0;39m Tomcat started on port 8080 (http) with context path '/'
[2m2024-08-04T20:48:25.037-03:00[0;39m [32m INFO[0;39m [35m23136[0;39m [2m---[0;39m [2m[projetoempresa] [  restartedMain][0;39m [2m[0;39m[36mb.c.c.p.ProjetoempresaApplication       [0;39m [2m:[0;39m Started ProjetoempresaApplication in 4.617 seconds (process running for 5.316)
[2m2024-08-04T20:48:30.052-03:00[0;39m [32m INFO[0;39m [35m23136[0;39m [2m---[0;39m [2m[projetoempresa] [nio-8080-exec-2][0;39m [2m[0;39m[36mo.a.c.c.C.[Tomcat].[localhost].[/]      [0;39m [2m:[0;39m Initializing Spring DispatcherServlet 'dispatcherServlet'
[2m2024-08-04T20:48:30.052-03:00[0;39m [32m INFO[0;39m [35m23136[0;39m [2m---[0;39m [2m[projetoempresa] [nio-8080-exec-2][0;39m [2m[0;39m[36mo.s.web.servlet.DispatcherServlet       [0;39m [2m:[0;39m Initializing Servlet 'dispatcherServlet'
[2m2024-08-04T20:48:30.054-03:00[0;39m [32m INFO[0;39m [35m23136[0;39m [2m---[0;39m [2m[projetoempresa] [nio-8080-exec-2][0;39m [2m[0;39m[36mo.s.web.servlet.DispatcherServlet       [0;39m [2m:[0;39m Completed initialization in 2 ms
Hibernate: select f1_0.num_funcional,f1_0.numero_id,f1_0.email,f1_0.nome,f1_0.salario from funcionario f1_0
Hibernate: select d1_0.numero_id,d1_0.andar,d1_0.nome from departamento d1_0 where d1_0.numero_id=?
Hibernate: select d1_0.numero_id,d1_0.andar,d1_0.nome from departamento d1_0 where d1_0.numero_id=?
Hibernate: select d1_0.numero_id,d1_0.andar,d1_0.nome from departamento d1_0 where d1_0.numero_id=?
Hibernate: select d1_0.numero_id,d1_0.andar,d1_0.nome from departamento d1_0 where d1_0.numero_id=?
Hibernate: select d1_0.numero_id,d1_0.andar,d1_0.nome from departamento d1_0 where d1_0.numero_id=?
Hibernate: select lf1_0.numero_id,lf1_0.num_funcional,lf1_0.email,lf1_0.nome,lf1_0.salario from funcionario lf1_0 where lf1_0.numero_id=?
[2m2024-08-04T20:48:30.464-03:00[0;39m [33m WARN[0;39m [35m23136[0;39m [2m---[0;39m [2m[projetoempresa] [nio-8080-exec-2][0;39m [2m[0;39m[36m.w.s.m.s.DefaultHandlerExceptionResolver[0;39m [2m:[0;39m Ignoring exception, response committed already: org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Document nesting depth (1001) exceeds the maximum allowed (1000, from `StreamWriteConstraints.getMaxNestingDepth()`)
[2m2024-08-04T20:48:30.465-03:00[0;39m [33m WARN[0;39m [35m23136[0;39m [2m---[0;39m [2m[projetoempresa] [nio-8080-exec-2][0;39m [2m[0;39m[36m.w.s.m.s.DefaultHandlerExceptionResolver[0;39m [2m:[0;39m Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Document nesting depth (1001) exceeds the maximum allowed (1000, from `StreamWriteConstraints.getMaxNestingDepth()`)]

How can I solve this problem without infinite references? I’d like to solve this:
a) when I try finding all Funcionarios should return like this:

NOW:

[
    {
        "numFuncional": 1,
        "nome": "Jose Alberto",
        "email": "[email protected]",
        "salario": 10000.0,
        "departamento": {
            "numeroId": 1,
            "nome": "Presidência",
            "andar": 1,
            "listaFuncionarios": [
                {
                    "numFuncional": 1,
                    "nome": "Jose Alberto",
                    "email": "[email protected]",
                    "salario": 10000.0,
                    "departamento": {
                        "numeroId": 1,
                        "nome": "Presidência",
                        "andar": 1,
                        "listaFuncionarios": [
                            {
                                "numFuncional": 1,
                                "nome": "Jose Alberto",
                                "email": "[email protected]",
                                "salario": 10000.0,
                                "departamento": {
                                    "numeroId": 1,
                                    "nome": "Presidência",
                                    "andar": 1,
                                    "listaFuncionarios": [

EXPECTATION:

[
    {
        "numFuncional": 1,
        "nome": "Jose Alberto",
        "email": "[email protected]",
        "salario": 10000.0,
        "departamento": {
            "numeroId": 1,
            "nome": "Presidência",
            "andar": 1
    }, 
    {
        "numFuncional": 3,
        "nome": "Pedro Oliveira",
        "email": "[email protected]",
        "salario": 6000.0,
        "departamento": {
            "numeroId": 3,
            "nome": "Infraestrutura",
            "andar": 2
    }, 
]

            

b) The same case, if I try finding Funcionario by ID

c) The same case, if I try finding all Departamentos or by ID;

I have a simple API Rest that aim my studies in Java.

Thanks guys!

2

Answers


  1. Chosen as BEST ANSWER

    The real problem is that my attribute: "DEPARTAMENTO" has Get and Set like "setDepartamento" and "getDepartamento", but the variable of the attribute is "depto". So I adjusted the get and set to:

    BEFORE:

    public Departamento getDepartamento() {
        return depto;
    }
    
    public void setDepartamento(Departamento departamento) {
        this.depto = departamento;
    }
    

    NOW:

    public Departamento getDepto() {
        return depto;
    }
    
    public void setDepto(Departamento depto) {
        this.depto = depto;
    }
    

    So the result of the Postman is OK in all the get Departamento and Funcionario:

    {
    "numFuncional": 1,
    "nome": "Jose Alberto",
    "email": "[email protected]",
    "salario": 10000.0,
    "depto": {
        "numeroId": 1,
        "nome": "Presidência",
        "andar": 1
    }
    

    }

    [
    {
        "numeroId": 1,
        "nome": "Presidência",
        "andar": 1,
        "listaFuncionarios": [
            {
                "numFuncional": 1,
                "nome": "Jose Alberto",
                "email": "[email protected]",
                "salario": 10000.0
            }
        ]
    },
    {
        "numeroId": 2,
        "nome": "Engenharia",
        "andar": 1,
        "listaFuncionarios": [
            {
                "numFuncional": 2,
                "nome": "Ana Pinheiro",
                "email": "[email protected]",
                "salario": 8000.0
            }
        ]
    }
    

    ]


  2. You putting wrong names.

    In your Departamento you have:

        @JsonIgnoreProperties("depto")
        private List<Funcionario> listaFuncionarios;
    

    It means you want to ignore depo property, but you don’t have one. You need to put @JsonIgnoreProperties("listaFuncionarios") to ignore listaFuncionarios property.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search