References lost at persistence time

Asked

Viewed 50 times

0

Below follow my entities and their relationships:

Order:

@Entity
@Table(name = "encomenda")
@XmlRootElement(name = "objeto")
@XmlAccessorType(XmlAccessType.FIELD)
public class Encomenda {

    @Getter
    @Setter
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Getter
    @Setter
    @Pattern(regexp = "[A-z]{2}\\d{9}[A-z]{2}", message = "O código não é válido")
    @Size(min = 13, max = 13, message = "É permitido 13 caracteres")
    @Column(nullable = false, length = 13)
    @NotBlank(message = "Nome não pode estar em branco")
    @XmlElement(name = "numero")
    private String codigo;

    @Getter
    @Setter
    @XmlElement(name = "evento")
    @OneToMany(mappedBy = "encomenda", targetEntity = Evento.class, cascade = CascadeType.ALL)
    private Collection<Evento> eventos;

    @Getter
    @Setter
    @Column
    private String loja;

    @Getter
    @Setter
    @XmlElement
    @Column
    private String erro;

Event:

@EqualsAndHashCode
@Entity
@Table(name = "evento")
@XmlRootElement(name="evento")
@XmlAccessorType(XmlAccessType.FIELD)
public class Evento {

    @Getter
    @Setter
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Getter
    @Setter
    @Column
    @XmlElement(name="data")
    private String dataOcorrencia;

    @Getter
    @Setter
    @Column
    @XmlElement(name="hora")
    private String horaOcorrencia;

    @Getter
    @Setter
    @Column
    @XmlElement
    private String descricao;

    @Getter
    @Setter
    @Column
    @XmlElement
    private String local;

    @Getter
    @Setter
    @Column
    @XmlElement
    private String cidade;

    @Getter
    @Setter
    @Column
    @XmlElement
    private String uf;

    @Getter
    @Setter
    @OneToOne(mappedBy="evento",cascade = CascadeType.ALL)
    @XmlElement(name="destino")
    private Destino destino;

    @Getter
    @Setter
    @ManyToOne
    private Encomenda encomenda;

In the database I have the tables event and order. In the event table have order_id which is FK. The big problem that by persisting the object order your id is normally generated as in the event table the id is generated, but the order field is null. Does anyone know how to resolve ?

The object is filled through an xml, the controller is like this:

@ManagedBean
@ViewScoped
public class EncomendaController {

    @Getter
    @Setter
    private Encomenda encomenda;

    @Getter
    @Setter
    private Collection<Encomenda> objetos;

    @Inject
    private EncomendaService service;

    @PostConstruct
    public void novo() {
        encomenda = new Encomenda();
    }

    public void salvar() throws IOException, SOAPException {
        if (encomenda.getId() == null) {
            try {
                popularObjeto(encomenda.getCodigo());
                service.insert(encomenda);
                JsfUtils.addInfoMessage("encomenda.cadastrada");
                encomenda = new Encomenda();
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            service.update(encomenda);
        }
    }

    private Encomenda popularObjeto(String codigo) throws IOException, SOAPException, JAXBException {
        String xml = RoboCorreios.consultarCodigo(codigo);

        JAXBContext context = JAXBContext.newInstance(Encomenda.class);
        Unmarshaller unmarshaller = context.createUnmarshaller();
        Encomenda objeto = (Encomenda) unmarshaller.unmarshal(new StringReader(xml));
        final boolean objetoExiste = objeto.getErro() == null ? true : false;

        if (objetoExiste) {
            setEncomenda(objeto);
            return encomenda;
        } else {
            encomenda.setErro("Objeto não localizado");
            return encomenda;
        }
    }

}

My Service:

@Stateless
@LocalBean
public class EncomendaService extends ServiceBase {

    public void insert(Encomenda objeto) {
        this.em.persist(objeto);
    }

    public void update(Encomenda objeto) {
        this.em.merge(objeto);
    }
  • Places the code that fills the object that is persisted in the database.

  • Ready @Giulianabezerra

  • That’s weird! It seems to be all right. Check your list of events in the order object to see if it is filled with the event reference. You would need at some point to set the order for each event in the list events equal to the order given pro Insert, understand? Because otherwise you will not be referencing the same order object and this may be the cause of the problem.

  • @Giulianabezerra debugging I saw that the events are not with the order reference, is null.

1 answer

2


The problem is that you did not associate the order reference in the event listing. One way to do this is to add a foreach to load the object into each item in the event list:

public void salvar() throws IOException, SOAPException {
        if (encomenda.getId() == null) {
            try {
                popularObjeto(encomenda.getCodigo());

                for (Evento evento : encomenda.getEventos()) {
                    evento.setEncomenda(encomenda);
                }
                service.insert(encomenda);
                JsfUtils.addInfoMessage("encomenda.cadastrada");
                encomenda = new Encomenda();
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            service.update(encomenda);
        }
    }

With this change the same order created will be associated to each of the events.

  • I made that same logic once and saw that it worked, but this is not the work of JPA? I say it because I may come across a situation that I will have many relationships.

  • It is Hibernate’s job to do Scade, popular the objects is his task. It would only fill out if you made a BD query and the attribute was mapped. For persistence is the developer who does.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.