9
respostas

Problema ao atualizar associação de entidades Hibernate/JavaEE

Estou fazendo uma API EM JAVA + Hibernate + Postgres, para ser consumida pelo meu front-end (Angular) e uma das classes possui uma associação @OneToMany com outra, porém quando edito/atualizo uma entidade, seus associados/filhos não atualizam. Sendo que já estou usando cascadeType.ALL que até onde eu intendi deveria atualizar não só aquela entidade mas as associadas a ela. Quando eu cadastro a entidade "pai" sem ter as entidades filhas cadastradas, ela cadastrada as entidades filhas primeiro antes de cadastrar a entidade pai. O relacionamento é ListaEventos e eventos. Sendo que uma ListaEventos tem varios eventos.Classe ListaEventos.

 @Getter
    @Setter
    @AllArgsConstructor
    @NoArgsConstructor
    @ToString
    @Entity
    @Table(name = "lista_eventos", schema = "public")
    public class ListaEventos implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String gameMaster;
    private Date dataEvento;
    private boolean checked;

    @Ignore
    public Long codigoUsuario;

    @OneToMany(cascade = CascadeType.ALL,
            mappedBy = "listaEventos",
            orphanRemoval = true)
    private List<Evento> eventos;

    @OneToOne(fetch = FetchType.EAGER)
    private Usuario usuario;

    public void associar() {
        for (Evento evento : eventos) {
            evento.setListaEventos(this);
        }
    }

    public void atualizarAssociacao(ListaEventos listaEventosAtualizada) {
        for (Evento evento : listaEventosAtualizada.getEventos()) {
            evento.setListaEventos(listaEventosAtualizada);
        }
    }

}
    @Table(name = "eventos", schema = "public")
     public class Evento implements Serializable {

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

    private String player;
    private String nome;
    private Integer premiacao;
    private String printUrl;

    @ManyToOne
    @JsonIgnore
    private ListaEventos listaEventos;
}

Quando é um @POST funciona o cadastro tranquilamente, mas quando é um @PUT meu front-end envia exatamente o que é pedido, porém o relacionamento não atualiza a entidade filha (evento), como eu faço para atualizar ela?

inserir a descrição da imagem aqui

Tentei atualizar dessa forma, só atualizou da entidade pai da relação, no caso

        ListaEventos.
        public ListaEventos atualizar(Long id, ListaEventos 
        listaEventosAtualizada){
        ListaEventos listaEventos = findById(id);
        listaEventos.setChecked(listaEventosAtualizada.isChecked());
        listaEventos.setDataEvento(listaEventosAtualizada.getDataEvento());
        listaEventos.setGameMaster(listaEventosAtualizada.getGameMaster());


        em.merge(listaEventos);
        return listaEventos;
    }
9 respostas

Boa noite Douglas! Aparentemente você está esquecendo de abrir e fechar sua transação, ex:

EntityManager em = new JPAUtil().getEntityManager();
em.getTransaction().
em.merge(listaEventos);
em.getTransaction().commit();
em.close();

curiosidade: Não é necessário buscar no banco de dados pelo id, pois se seu objeto tem um id válido ele já é managed, basta que você passar a lista de eventos atualizada.

só uma dúvida, como vc fez para inserir uma imagem na sua pergunta?

Olá Ramires,

Estou usando o wildfly ele abstrai a necessidade de precisar iniciar ou fechar transações.

Sobre a imagem, apenas o link mesmo.

Tenta fazer o merge com a lista que você recebe como parâmetro

Não intendi, eu acredito que já esteja fazendo o merge.

 ListaEventos.
        public ListaEventos atualizar(Long id, ListaEventos 
        listaEventosAtualizada){
        ListaEventos listaEventos = findById(id);
        listaEventos.setChecked(listaEventosAtualizada.isChecked());
        listaEventos.setDataEvento(listaEventosAtualizada.getDataEvento());
        listaEventos.setGameMaster(listaEventosAtualizada.getGameMaster());


        em.merge(listaEventos);
        return listaEventos;
    }

Douglas o seu código deixa parecer que você só quer atualizar a lista de eventos, e não o evento em si, posta aqui o JSON que você envia.

{
    "gameMaster":"GameMaster1",
    "dataEvento":"2017-04-04",
    "checked":true,
    "eventos":[{
        "player": "Player1",
        "nome":"Mata-Mata2",
        "premiacao": 50,
        "printUrl":"print"
    },{
        "player": "Player2",
        "nome":"Mata-Mata2",
        "premiacao": 100,
        "printUrl":"print2"
    }]
 }

E por exemplo, se eu alterar o "Player2"pra "Player3" ele não atualiza. Atualiza só uma informação que eu atualizar no dono da associação, no caso no ListaEventos, por exemplo se eu alterar o "gameMaster" ele atualiza como deveria.

É justamente o que estou lhe dizendo, passe para o método merge a lista de eventos que você recebe exemplo:

public ListaEventos atualizar(Long id, ListaEventos 
        listaEventosAtualizada){
        em.merge(listaEventosAtualizada);
        return listaEventosAtualizada;
    }

não faça a busca no banco de dados, apenas atualize a lista que você recebe, tal qual eu fiz

Importante: os eventos devem ter ID válido ex:

{
    "id": 50, //id válido
    "gameMaster":"GameMaster1",
    "dataEvento":"2017-04-04",
    "checked":true,
    "eventos":[{
        "id": 12 // id válido
        "player": "Player1",
        "nome":"Mata-Mata2",
        "premiacao": 50,
        "printUrl":"print"
    },{
        "id": 13 // id válido
        "player": "Player2",
        "nome":"Mata-Mata2",
        "premiacao": 100,
        "printUrl":"print2"
    }]
 }

deu certo?