OneToMany possui uma lista mas nunca nenhum registro!

7 respostas
R

Olá,

Possuo 3 entidades. ASN, ASNUSUARIOS e USUARIO.
A primeira se relaciona com a última através da segunda entidade.
Como essa relação possui "estado" tive de criar esta segunda entidade para resolver o problema.
No final as relações entre elas foram definidas da seguinte forma:

@OneToMany(mappedBy = "asn")
    private List<ASNUsuarios> asnUsuarios = new ArrayList<ASNUsuarios>();
@NotNull
    @ManyToOne
    @JoinColumn(name="idAsn", referencedColumnName="ID")
    private ASN asn;

    @NotNull
    @ManyToOne
    @JoinColumn(name="idUsuario", referencedColumnName="ID")
    private Usuario idUsuario;

    @NotNull
    @Column(nullable=false)
    private String tipoUsuario;
@OneToMany(mappedBy="idUsuario")
    private List<ASNUsuarios> asnUsuarios = new ArrayList<ASNUsuarios>();

O problema é que apesar de existir uma entrada na tabela ASNUSUARIOS, ou seja, apesar de existir um relacionamento entre o Usuário e um ASN, eu não consigo acessa-las através das entidades Usuario/ASN. A lista está sempre vazia.

Porque?

7 Respostas

mrrbigu

Para que o hibernate preencha a tabela de ligação ASNUSUARIOS, você terá que informá-la através da anotação @JoinTable, e fazer o relacionamento como se fosse diretamente entre as tabelas ASN e USUARIOS.
Há também outros problemas em seu código, pois se ele é @OneToMany, ASN terá que ter uma lista de usuários, mas na classe Usuario, a anotação correta é @ManyToOne, e ela terá um atributo ASN e não uma lista. Como na sua classe você usou lista dos dois lados, aparenta que na verdade você está precisando utilizar uma relação ManyToMany.
Com essa contradição não dá para dar um exemplo exato, mas vou tentar dar um exemplo:

A classe Asn seria mais ou menos assim:

@OneToMany(cascade = CascadeType.ALL) @JoinTable(name = "ASNUSUARIOS", joinColumns = { @JoinColumn(name = "ID_ASN") }, inverseJoinColumns = { @JoinColumn(name = "ID_USUARIO") }) private List<Usuario> asnUsuarios = new ArrayList<Usuario>();

A tabela ASNUSUARIOS não precisa ser mapeada em uma classe, basta existir no banco.

R

Muito obrigado pela resposta,

Eu realmente gostaria de uma relação ManyToMany, porém como esta relação possui um estado (tipoDeUsuario) fui orientado a fazer desta maneira, com uma entidade no meio fazendo a ponte entre as duas.

Voce poderia me dizer o que quer dizer “inverseJoinColumns”?

R

Ah, eu andei lendo por ai que usar many to many não é uma boa prática e que o correto é se usar “do jeito que eu fiz”, com uma entidade no meio. O problema é que eu sou novo no JPA tudo que fiz foi com ajuda de terceiros.

mrrbigu

Ricardo, o ManytoMany do jeito que te passei possui uma entidade no meio, uma tabela que fará a ligação entre as duas outras tabelas, e que caso necessário poderá possuir outros campos além das chaves primárias das duas tabelas relacionadas. Como diz a documentação:

http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/mapping.html#d0e7517

Ou seja, nesse caso o inverseJoinColumns é usada para referenciar a chave primária da tabela do outro lado da relação ManytoMany.

R

Hum, eu acho que entendi.
Minhas classes ficaram assim:

@JoinTable(name = "ASNUSUARIOS", joinColumns = { @JoinColumn(name = "ID_ASN") }, inverseJoinColumns = { @JoinColumn(name = "ID_USUARIO") }) @OneToMany(mappedBy = "asn", cascade=CascadeType.ALL) private List<ASNUsuarios> asnUsuarios = new ArrayList<ASNUsuarios>();

e

@JoinTable(name = "ASNUSUARIOS", joinColumns = { @JoinColumn(name = "ID_USUARIO") }, inverseJoinColumns = { @JoinColumn(name = "ID_ASN") }) @OneToMany(mappedBy = "idUsuario") private List<ASNUsuarios> asnUsuarios = new ArrayList<ASNUsuarios>();

Mas mesmo assim não consegui. Desculpe a minha burrice, estou tentando aprender. Estou lendo o livro Pro JPA , mas sou muito jumentinho ainda.

mrrbigu

Veja bem, você tinha dito que no seu caso era melhor usar ManyToMany, e você colocou OneToMany no código, mas manteve lista dos dois lados, o que como o nome da relação já diz não dá.
Além disso, na classe AS a lista é de USUARIOS, e não de ASNUsuarios, e na classe USUARIOS a lista é de AS e não de ASNUsuarios, como postei anteriormente, a tabela ASNUSUARIOS só aparece na anotação @JoinTable e sequer precisa ser mapeada para uma classe.

R

Sim, entendi.

Vou mudar o relacionamento para ManyToMany. Muito obrigado.

Criado 5 de novembro de 2010
Ultima resposta 9 de nov. de 2010
Respostas 7
Participantes 2