JSONWriter上的Gson StackOverflow

时间:2015-02-20 13:23:56

标签: json hibernate jersey gson

我创建了一个系统,并通过Webservice Restful进行了libero访问,我发布了一个维护列表,这个列表由对象组成:Cliente, Endereco, Manutencao, StatusManutencao

我有一个类来寻找所有维护的类:PesquisaManutencoesWebService,接收调用webservice的类调用SimpleRestService

当我在JSON(return gson.toJson (ws.getJson ());)中转换维护列表时,会产生以下错误:

java.lang.StackOverflowError
java.io.StringWriter.write (StringWriter.java:112)
com.google.gson.stream.JsonWriter.string (JsonWriter.java:559)
com.google.gson.stream.JsonWriter.writeDeferredName (JsonWriter.java:402)
com.google.gson.stream.JsonWriter.value (JsonWriter.java:495)
com.google.gson.internal.bind.TypeAdapters $ 8.write (TypeAdapters.java:268)

已经测试过列表是否正常工作,实际上,我可以获得我想要的所有数据,但我不能变成JSON。

任何人都可以帮助我吗?感谢。

Class Cliente

@Entity
@Table(name = "cliente")
public class Cliente implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue
private Long id;

@NotBlank @Size(max = 6)
@Column(nullable = false, length = 6)
private String codigoAcesso;

@NotBlank @Size(max = 100)
@Column(nullable = false, length = 100)
private String nome;

@Size(max = 150)
@Column(nullable = true, length = 150)
private String email;

@NotBlank @Size(max = 14)
@Column(name = "doc_receita_federal", nullable = false, length = 14)
private String documentoReceitaFederal;

@Enumerated(EnumType.STRING)
@Column(nullable = false, length = 15)
private TipoPessoa tipo;

@OneToMany(mappedBy = "cliente", cascade = CascadeType.ALL)
private List<Endereco> enderecos = new ArrayList<>();

班级Endereco

@Entity
@Table(name = "endereco")
public class Endereco implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue
private Long id;

@NotBlank @Size(max = 150)
@Column(nullable = false, length = 150)
private String logradouro;

@NotBlank @Size(max = 20)
@Column(nullable = false, length = 20)
private String numero;

@Size(max = 100)
@Column(length = 100)
private String complemento;

@NotBlank @Size(max = 100)
@Column(nullable = false, length = 100)
private String cidade;

@NotBlank @Size(max = 100)
@Column(nullable = false, length = 100)
private String uf;

@NotBlank @Size(max = 8)
@Column(nullable = false, length = 8)
private String cep;

//@NotBlank
@ManyToOne
@JoinColumn(name = "cliente_id", nullable = false)
private Cliente cliente;

getters and setters ...

类Manutencao

@Entity
@Table(name = "manutencao")
public class Manutencao implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue
private Long id;

@ManyToOne
@JoinColumn(name = "cliente_id")
private Cliente cliente;

@Embedded
private StatusManutencao status;

@NotBlank 
@Column(nullable = false, length = 255, name="descricao_manutencao")
private String descricaoManutencao;

@Column(name = "valor", precision = 10, scale = 2)
private BigDecimal valor;

getters and setters ...

Class StatusManutencao

@Embeddable
public class StatusManutencao implements Serializable {

private static final long serialVersionUID = 1L;

@Column(name="recebido")
@Type(type="true_false")
private boolean recebido;

@Temporal(TemporalType.DATE)
@Column(name="data_recebimento")
private Date dataRecebimento;

@Column(name="em_manutencao")
@Type(type="true_false")
private boolean emManutencao;

@Temporal(TemporalType.DATE)
@Column(name="data_manutencao")
private Date dataManutencao;

@Column(name="manutencao_finalizada")
@Type(type="true_false")
private boolean manutencaoFinalizada;

@Temporal(TemporalType.DATE)
@Column(name="data_finalizacao")
private Date dataFinalizacao;

@Column(name="entregue")
@Type(type="true_false")
private boolean entregue;

@Temporal(TemporalType.DATE)
@Column(name="data_entrega")
private Date dataEntrega;

@Column(name="pago")
@Type(type="true_false")
private boolean pago;

@Temporal(TemporalType.DATE)
@Column(name="data_pagamento")
private Date dataPagamento;

getters and setters ...

Class PesquisaManutencaoWebService

public class PesquisaManutencoesWebService implements Serializable {

private static final long serialVersionUID = 1L;

private EntityManager manager;
private EntityManagerFactory factory;
private EntityTransaction trx;


public PesquisaManutencoesWebService(){
    this.factory = Persistence.createEntityManagerFactory("ManutencaoPU");
    this.manager = factory.createEntityManager();
    this.trx = manager.getTransaction();
    this.trx.begin();
}

@SuppressWarnings("unchecked")
public JsonModel getJson(){
    List<Manutencao> manutencoes = manager.createQuery("SELECT m FROM Manutencao m").getResultList();
    return new JsonModel(manutencoes);
}
}

Class SimpleRestService

@Path("service")
public class SimpleRestService {

private PesquisaManutencoesWebService ws;

@GET
@Produces("application/json")
@Path("/{codigoAcesso}/")
public String getManutencoes(@PathParam("codigoAcesso") String codigoAcesso) throws IOException, SQLException, ClassNotFoundException{
    ws = new PesquisaManutencoesWebService();
    Gson gson = new GsonBuilder().serializeSpecialFloatingPointValues().setPrettyPrinting().create();
    return gson.toJson(ws.getJson());
}
}

1 个答案:

答案 0 :(得分:0)

在大多数情况下,当调用堆栈超过时会抛出StackOverError,因为过度的深度或无限递归。当在方法中存储局部变量的需要超过分配的堆栈大小时,也会抛出它。

Endereco 类中,将获取类型添加到Cliente属性中的@ManyToOne anotattion,然后您的代码应如下所示:

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "cliente_id")
private Cliente cliente;

当您将FetchType设置为 Lazy 时,您基本上是说实体不应该嵌套到父实体。

然后尝试手动获取 Clientes 列表...