Giter VIP home page Giter VIP logo

Comments (13)

cowtowncoder avatar cowtowncoder commented on August 29, 2024

I am not sure what the question here is. Would it be possible to have a bit of code that uses this model, exposes the issue?

from jackson-annotations.

mandado avatar mandado commented on August 29, 2024

Method is listaratividades() , i'm was used spring data to abstract repository code.
i was debug code and see that spring data returns all data correctly with relationship, but relationship not injected a json response.

Atividade Controller

package app.controller;

import app.lib.ValidationMessage;
import app.model.Atividade;
import app.model.Local;
import app.repository.AtividadeRepository;
import app.repository.LocalRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.ArrayList;


/**
 * Created by jorge on 27/05/15.
 */
@RestController
@RequestMapping("api/")
public class AtividadeController {
    @Autowired
    private AtividadeRepository repository;
    @Autowired
    private LocalRepository localRepository;

    @RequestMapping(value = "atividade", method = RequestMethod.POST)
    @ResponseBody public ResponseEntity novoatividade(@RequestBody @Valid Atividade atividade, BindingResult result) {
        Local local = localRepository.findOne(atividade.getLocal().getId());
        atividade.setLocal(local);
        if (result.hasErrors()) {
            validate(result);
        }
        return new ResponseEntity(repository.save(atividade), HttpStatus.OK);
    }

    @RequestMapping(value = "atividade", method = RequestMethod.GET)
    @ResponseBody
    public Iterable<Atividade> listaratividades() {
        return repository.findAll();
    }

    @RequestMapping(value = "atividade/{id}", method = RequestMethod.GET)
    public Atividade buscaratividade(@PathVariable Long id) {
        return repository.findOne(id);
    }

    @RequestMapping(value = "atividade/{id}", method = RequestMethod.DELETE)
    public void deletaratividade(@PathVariable Long id) {
        repository.delete(id);
    }

    @RequestMapping(value = "atividade", method = RequestMethod.PUT)
    public ResponseEntity editaratividade(@RequestBody @Valid Atividade atividade, BindingResult result) {
        if (result.hasErrors()) {
            validate(result);
        }
        return new ResponseEntity(repository.save(atividade), HttpStatus.OK);
    }

    private ResponseEntity validate(BindingResult result) {
        ArrayList<String> errors = ValidationMessage.parse(result.getAllErrors());
        return new ResponseEntity(errors, HttpStatus.BAD_REQUEST);
    }
}

AtividadeRepository

package app.repository;

import app.model.Atividade;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;

/**
 * Created by jorge on 01/06/15.
 */
@Component
@Repository
public interface AtividadeRepository extends CrudRepository<Atividade,Long> {

}

from jackson-annotations.

cowtowncoder avatar cowtowncoder commented on August 29, 2024

Unfortunately I am not familiar with Spring, so I would need a stand-alone test case.

One thing to note on managed/back reference is that it must always be traversed from managed to back reference: meaning that parent object must be serialized first. If traversal may be in either direction, this approach will not work, and the more generic Object Id handling (via @JsonIdentityInfo, usually) is needed.

from jackson-annotations.

mandado avatar mandado commented on August 29, 2024

but @jsonIdentityInfo returns this error

Could not read JSON: Unresolved forward references for: Object id [42] (for class app.model.Local) at [Source: java.io.PushbackInputStream@17ad297; line: 1, column: 343].; nested exception is com.fasterxml.jackson.databind.deser.UnresolvedForwardReference: Unresolved forward references for: Object id

when execute insert or update operation.

I mapped Atividade and Local model with @jsonIdentityInfo

Atividade Model

package app.model;

import com.fasterxml.jackson.annotation.*;
import org.springframework.data.jpa.domain.AbstractPersistable;

import javax.persistence.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by jorge on 26/04/15.
 */
@Entity
@Table(name = "atividade")
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id")
public class Atividade extends AbstractPersistable<Long>{

    @Column(name = "nome")
    private String nome;

    @Column(name = "descricao")
    private String descricao;

    @Column(name = "tipo")
    private Long tipo;

    @Column(name = "prerequisito")
    private String prerequisito;

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

    @Column(name = "hora_inicio")
    @Temporal(TemporalType.TIME)
    private Date hora_inicio;

    @Column(name = "hora_fim")
    @Temporal(TemporalType.TIME)
    private Date hora_fim;

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

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

    @Column(name = "valor_investimento")
    private BigDecimal valor_investimento;

    @Column(name = "valor_desconto")
    private BigDecimal valor_desconto;

    @ManyToOne
    @JoinColumn(name = "local_id")
    private Local local;

    @ManyToMany
    @JoinTable(name = "palestrante_atividade",
    joinColumns = {
            @JoinColumn(name = "id_atividade")
    },inverseJoinColumns = {
            @JoinColumn(name = "id_palestrante")
    })
    private List<Palestrante> palestrantes = new ArrayList<Palestrante>();

    public Atividade() {
    }

    public Atividade(String nome, String descricao, Long tipo, String prerequisito, Date data, Date hora_inicio, Date hora_fim, Date inscricoes_inicio, Date inscricoes_fim, BigDecimal valor_investimento, BigDecimal valor_desconto) {
        this.nome = nome;
        this.descricao = descricao;
        this.tipo = tipo;
        this.prerequisito = prerequisito;
        this.data = data;
        this.hora_inicio = hora_inicio;
        this.hora_fim = hora_fim;
        this.inscricoes_inicio = inscricoes_inicio;
        this.inscricoes_fim = inscricoes_fim;
        this.valor_investimento = valor_investimento;
        this.valor_desconto = valor_desconto;
    }

    public Atividade(String nome, String descricao, Long tipo, String prerequisito, Date data, Date hora_inicio, Date hora_fim, Date inscricoes_inicio, Date inscricoes_fim, BigDecimal valor_investimento, BigDecimal valor_desconto, Local local, ArrayList<Palestrante> palestrantes) {
        this.nome = nome;
        this.descricao = descricao;
        this.tipo = tipo;
        this.prerequisito = prerequisito;
        this.data = data;
        this.hora_inicio = hora_inicio;
        this.hora_fim = hora_fim;
        this.inscricoes_inicio = inscricoes_inicio;
        this.inscricoes_fim = inscricoes_fim;
        this.valor_investimento = valor_investimento;
        this.valor_desconto = valor_desconto;
        this.local = local;
        this.palestrantes = palestrantes;
    }

    public String getNome() {
        return nome;
    }

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

    public String getDescricao() {
        return descricao;
    }

    public void setDescricao(String descricao) {
        this.descricao = descricao;
    }

    public Long getTipo() {
        return tipo;
    }

    public void setTipo(Long tipo) {
        this.tipo = tipo;
    }

    public String getPrerequisito() {
        return prerequisito;
    }

    public void setPrerequisito(String prerequisito) {
        this.prerequisito = prerequisito;
    }

    public Date getData() {
        return data;
    }

    public void setData(Date data) {
        this.data = data;
    }

    public Date getHora_inicio() {
        return hora_inicio;
    }

    public void setHora_inicio(Date hora_inicio) {
        this.hora_inicio = hora_inicio;
    }

    public Date getHora_fim() {
        return hora_fim;
    }

    public void setHora_fim(Date hora_fim) {
        this.hora_fim = hora_fim;
    }

    public Date getInscricoes_inicio() {
        return inscricoes_inicio;
    }

    public void setInscricoes_inicio(Date inscricoes_inicio) {
        this.inscricoes_inicio = inscricoes_inicio;
    }

    public Date getInscricoes_fim() {
        return inscricoes_fim;
    }

    public void setInscricoes_fim(Date inscricoes_fim) {
        this.inscricoes_fim = inscricoes_fim;
    }

    public BigDecimal getValor_investimento() {
        return valor_investimento;
    }

    public void setValor_investimento(BigDecimal valor_investimento) {
        this.valor_investimento = valor_investimento;
    }

    public BigDecimal getValor_desconto() {
        return valor_desconto;
    }

    public void setValor_desconto(BigDecimal desconto_aluno) {
        this.valor_desconto = desconto_aluno;
    }
    public Local getLocal() {
        return local;
    }

    public void setLocal(Local local) {
        this.local = local;
    }

    public List<Palestrante> getPalestrantes() {
        return palestrantes;
    }

    public void setPalestrantes(ArrayList<Palestrante> palestrantes) {
        this.palestrantes = palestrantes;
    }
}

Local Model

package app.model;

import com.fasterxml.jackson.annotation.*;

import org.springframework.data.jpa.domain.AbstractPersistable;

import javax.persistence.*;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by jorge on 26/04/15.
 */
@Entity
@Table(name = "local")
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id")
public class Local extends AbstractPersistable<Long>{

    @Column(name = "cnpj")
    private  String cnpj;

    @Column(name = "nome")
    private  String nome;

    @Column(name = "tel")
    private  String tel;

    @Column(name = "rua")
    private  String rua;

    @Column(name = "bairro")
    private  String bairro;

    @Column(name = "cidade")
    private  String cidade;

    @Column(name = "estado")
    private  String estado;

    @Column(name = "descricao")
    private  String descricao;

    @Column(name = "capacidade_lotacao")
    @JsonProperty("capacidade_lotacao")
    private  Long capacidade_lotacao;

    @OneToMany(mappedBy = "local", targetEntity = Atividade.class,cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private  List<Atividade> atividades;

    public Local() {
    }

    public Local(Long id) {
        this.setId(id);
    }

    public Local( String cnpj, String nome, String tel, String rua, String bairro, String cidade, String estado, String descricao, Long capacidade_lotacao) {
        this.cnpj = cnpj;
        this.nome = nome;
        this.tel = tel;
        this.rua = rua;
        this.bairro = bairro;
        this.cidade = cidade;
        this.estado = estado;
        this.descricao = descricao;
        this.capacidade_lotacao = capacidade_lotacao;
    }

    public Local( String cnpj, String nome, String tel, String rua, String bairro, String cidade, String estado, String descricao, Long capacidade_lotacao, List<Atividade> atividades) {
        this.cnpj = cnpj;
        this.nome = nome;
        this.tel = tel;
        this.rua = rua;
        this.bairro = bairro;
        this.cidade = cidade;
        this.estado = estado;
        this.descricao = descricao;
        this.capacidade_lotacao = capacidade_lotacao;
        this.atividades = atividades;
    }

    public String getCnpj() {
        return cnpj;
    }

    public void setCnpj(String cnpj) {
        this.cnpj = cnpj;
    }

    public String getNome() {
        return nome;
    }

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

    public String getTel() {
        return tel;
    }

    public void setTel(String tel) {
        this.tel = tel;
    }

    public String getRua() {
        return rua;
    }

    public void setRua(String rua) {
        this.rua = rua;
    }

    public String getBairro() {
        return bairro;
    }

    public void setBairro(String bairro) {
        this.bairro = bairro;
    }

    public String getCidade() {
        return cidade;
    }

    public void setCidade(String cidade) {
        this.cidade = cidade;
    }

    public String getEstado() {
        return estado;
    }

    public void setEstado(String estado) {
        this.estado = estado;
    }

    public String getDescricao() {
        return descricao;
    }

    public void setDescricao(String descricao) {
        this.descricao = descricao;
    }


    public Long getCapacidade_lotacao() {
        return capacidade_lotacao;
    }

    public void setCapacidade_lotacao(Long capacidade_lotacao) {
        this.capacidade_lotacao = capacidade_lotacao;
    }

    public List<Atividade> getAtividades() {

        if(atividades == null){
            atividades = new ArrayList<Atividade>();
        }
        return atividades;
    }

    public void setAtividades(List<Atividade> atividades) {
        this.atividades = atividades;
    }
}

from jackson-annotations.

cowtowncoder avatar cowtowncoder commented on August 29, 2024

Correct: you must provide an id to be able to serialize or deserialize Object Ids.

from jackson-annotations.

mandado avatar mandado commented on August 29, 2024

what do you mean ? id must come model ? in my collection of atividade have id.

Atividade Response

[
    {
        "@id": 1,
        "id": 43,
        "nome": "teste",
        "descricao": "teste",
        "tipo": 1,
        "prerequisito": "teste",
        "data": "1499-12-31",
        "hora_inicio": "00:01:00",
        "hora_fim": "00:01:00",
        "inscricoes_inicio": "1970-01-01",
        "inscricoes_fim": "1970-01-01",
        "valor_investimento": 12,
        "valor_desconto": 12,
        "local": {
            "@id": 1,
            "id": 42,
            "cnpj": "123456",
            "nome": "teste",
            "tel": "123456",
            "rua": "456",
            "bairro": "123",
            "cidade": "123",
            "estado": "mg",
            "descricao": "1234",
            "atividades": [
                1,
                2
            ],
            "new": false,
            "capacidade_lotacao": 1023456
        },
        "palestrantes": [],
        "new": false
    },
    {
        "@id": 3,
        "id": 44,
        "nome": "testador",
        "descricao": "123",
        "tipo": 1,
        "prerequisito": "1",
        "data": "1995-06-10",
        "hora_inicio": "00:01:00",
        "hora_fim": "00:00:00",
        "inscricoes_inicio": "1970-01-01",
        "inscricoes_fim": "1970-01-01",
        "valor_investimento": 1,
        "valor_desconto": 1,
        "local": 1,
        "palestrantes": [],
        "new": false
    }
]

from jackson-annotations.

cowtowncoder avatar cowtowncoder commented on August 29, 2024

What I am saying that the exception you mention indicates that an object id reference found from JSON did not point to id of any other Object within JSON. In this case,

Looking at JSON, it looks like there are 2 id properties; "id" and "@id". Maybe that is not intended, and only "id" should be used? If so, @JsonIdentityInfo annotation should use that.
It depends on whether you want to generate different ids than those stored in the database (use just one id), or separate ones (use id and @id).
As things are configured I guess you do want to use separate ids, and this is why '@id' is added.

Looking at class definition and JSON, exception does not look right however: 42 is never used as a reference. Is it possible that you may have "id" in @JsonIdentityInfo locally, and not like class definition above?

from jackson-annotations.

mandado avatar mandado commented on August 29, 2024

what do you mean with @JsonIdentityInfo locally ? i changed @id to id, because i resolved to use one id only to store in database. but 42 is reference from local relationship and i got the same error of Unsolved forward references... .

@JsonManagedReference and @JsonBackReference should breaking cyclic reference in json and solve this, without using @JsonIdentityInfo ?

from jackson-annotations.

cowtowncoder avatar cowtowncoder commented on August 29, 2024

JsonManagedReference and JsonBackReference are mechanims to transparently handle simple uni-directional parent/child relationship, without adding or using ids. But they can not handle arbitrary cyclic relationships, where there is no natural parent/child relation. I am assuming that your problem is that sometimes you are serializing things starting with child, othertimes with parent: if so, it will not work. But your example is big enough that I am not sure. Cutting code size down to just id and a single field, and dropping database-dependant annotations would help.

If you do need general handling of cyclic dependencies, @JsonIdentityInfo can do that, but it then requires use of ids; either existing ones (provided by POJOs), or generated ones (where Jackson generates object id as metadata, and POJO does NOT have matching property).

As to id vs @id, as long as you do want two sets of ids that is fine. I just wanted to verify that was intentional and not accidental. Either usage (one or two) is valid in itself.

from jackson-annotations.

mandado avatar mandado commented on August 29, 2024

two ids was accidental, so it was changed @JsonIdentityInfo (generator = ObjectIdGenerators.IntSequenceGenerator.class, property =" @ id ') para @JsonIdentityInfo (generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "id" ).
but still keeps giving problem. my intention was to use only id.

from jackson-annotations.

cowtowncoder avatar cowtowncoder commented on August 29, 2024

At this point what is needed is a smaller reproducible test case. It should be filed against jackson-databind, because while this package adds anntoations, databind actually handles them.
For usage questions, please use google groups (https://groups.google.com/forum/#!forum/jackson-user).

There is also commercial support for jackson via FasterXML ([email protected]) available.

At this point I do not answer questions via my personal email since the volume has gotten high, and all of that support is unpaid work and is starting to compete with my job.

from jackson-annotations.

mandado avatar mandado commented on August 29, 2024

Thanks, i go to post in google groups.

from jackson-annotations.

cowtowncoder avatar cowtowncoder commented on August 29, 2024

Saw your messages, good -- I hope the issue gets resolved, and will try to help as well.

from jackson-annotations.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.