5
respostas

Como conhecer o id gerado para uma entidade gerenciada?

Boa tarde!

Tenho duas entidade que se relacionam (Atividade e Questao). Na Atividade tenho um método que adiciona questões (adicionaQuestao). Eu precisaria saber o id que “questao” recebe após atividade ser persistida.

Exemplo:

Questao questao = new Questao...

AtividadeDAO atividadeDAO = new AtividadeDAO(); // EntityManager injetado no objeto
Atividade atividade = atividadeDAO.busca(atividadeId);
atividade.adicionaQuestao(questao);   // << aqui - o id que "questao" vai ganhar...
atividadeDAO.salvar(atividade);

No primeiro momento pensei que o objeto “questao” receberia o id após atividade ser salva (merge, nesse caso), mas não, o id permanece null.

No primeiro momento imaginei que seria como o caso de uma única entidade sendo persistida, como o exemplo abaixo:

Atividade atividade = new Atividade();
atividade.set...

AtividdeDAO atividadeDAO = new AtividadeDAO();
atividadeDAO.salvar(atividade);  // aqui "atividade" recebe um id

Parte das entidades das quais falei:

@Entity
@Table(name = "atividades")
public class Atividade {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @NotNull
    private String descricao;

    @OneToMany(mappedBy = "atividade", cascade = { CascadeType.PERSIST, CascadeType.MERGE })
    private List<Questao> questoes = new ArrayList<>();

    // mais métodos e atributos

    public void adicionaQuestao(Questao questao) {
        this.questoes.add(questao);
        questao.setAtividade(this);
    }
}

@Entity
@Table(name = "questoes")
public class Questao {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @NotNull
    private String enunciado;

    @ManyToOne(optional = false)
    @JoinColumn(name = "atividade_id", nullable = false)
    private Atividade atividade;

    // mais métodos e atributos

    public void setAtividade(Atividade atividade) {
        this.atividade = atividade;
    }
}

Será que pra conhecer o id que questao recebe vou precisar fazer o procedimento de persistência exclusivamente para a entidade questao por fora (sem usar o adicionaQuestao da entidade Atividade)?

Tipo o seguinte:

questaoDAO.salvar(questao);

?

Desde já agradeço

5 respostas

É que no método que adiciona vc ainda não salvou a atividade, né? Aí não vai ter mesmo.. Ou o id não apareceu na questão mesmo depois de vc ter salvo a atividade?

Oi Alberto.

Mesmo depois de salvar a atividade o id de questão permanece null.

hummm... pode ser que o comportamento seja diferente mesmo... De todo jeito, acho que vai ser bom para o seu sistema tirar o cascade e deixar tudo explicito no código :).

Tá certo. Eu estava montando todos os mapeamentos e fazendo os testes (já considerando como testes de integração). Mas agora montando o sistema com as views tenho percebido necessidades que antes não havia enxergado, como alguns relacionamentos bidirecionais e esses controles de persistência que questionei nesse post.

É coisa de iniciante. Mas com o tempo a gente aprende.

Muito obrigado Alberto.

Boa tarde.

Eu implementei de forma explicita a persistência em cada entidade filha (como o Alberto sugeriu) - para o sistema andar.

O Alberto já deu a contribuição dele (e eu agradeço). Mas gostaria de saber dos demais se o comportamento é esse mesmo. Ninguém é obrigado a saber tudo, pode ser que Alberto ainda não saiba.

Sempre se fala em dar comportamento para as entidades e nos posts que tratam de persistência em entidades pai e filha, geralmente se usa esses métodos (classePai.adicionaFilho). Um exemplo de uso está no curso de collections ministrado pelo Paulo - claro que lá não houve persistência, apenas a manipulação das coleções em memória. Mas creio que foi uma simulação do que se usa na prática.