Jackson em projeto Spring Boot geram referência cíclica

O Jackson é utilizado para conversão de objetos em json e vem sendo utilizado pelo spring a muito tempo. No Spring Boot comecei a ver referências cíclicas, neste post vou mostrar como resolver isso.

Wolmir Cezer Garbin por Wolmir Cezer Garbin - - Java - TUTORIAL

Última atualização em: | 6234 Visualizações

Se estiver com problema de referência cíclica utilizando um micro serviço em Spring Boot, Jackson e Lombok, este post vai te ajudar a resolver.

Versões utilizadas


  • Spring Boot 1.5.2.RELEASE
  • Jakson 2.8
  • Lombok 1.16.14

O problema

Quando criamos serviços utilizando spring boot e o jackson, pode acontecer de ter referência cíclica.

Para entender melhor o problema veja o código:

import lombok.*;
import javax.persistence.*;

@Entity
@Table(name = "MENU")
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(of = {"id"})
public class Menu {

	@Id
	@Column(name = "ID")
	private Long id;

	// [...]

	@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name = "MENUPAI")
	private Menu menuPai;
				
	@OneToMany(mappedBy = "menuPai", fetch = FetchType.EAGER)
	private List<Menu> lsFilhos;
}

Sempre que um menu contiver filhos, este caregará os mesmos em uma lista de filhos os quais carregaram os pais, e assim cria uma sequência infinita de iterações, gerando erro na conversão.

Para resolver o problema podemos utilizar um @JsonIgnore, porém, se anotar a própriedade menuPai isso não vai funcionar. Analisando o problema percebemos que o Jackson obtem os valores a partir dos métodos get o qual é gerado pelo lombok, desta forma vamos mostrar a solução que encontramos.

A solução

Para nós a solução foi criar o método get da própriedade e anotar com @JsonIgnore. Veja o código com o problema resolvido:

import lombok.*;
import javax.persistence.*;

@Entity
@Table(name = "MENU")
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(of = {"id"})
public class Menu {

	@Id
	@Column(name = "ID")
	private Long id;

	// [...]

	@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name = "MENUPAI")
	private Menu menuPai;
				
	@OneToMany(mappedBy = "menuPai", fetch = FetchType.EAGER)
	private List<Menu> lsFilhos;
	
	@JsonIgnore
	public AplicacaoMenu getMenuPai() {
		 return menuPai;
	}
}

Pronto! O problema será resolvido, qualquer dúvida poste nos comentários e te ajudaremos.


Não esqueca de deixar suas dúvidas nos comentários e compartilhar este post.


Apoiadores

Publique seu post no Receitas de Código

Aguarde, estamos trabalhando para que você possa publicar sua postagem no Receitas de Código!