mappedBy - Hibernate

@Entity public class Categoria implements Serializable { private Collection<Exame> exames; //... @OneToMany public Collection<Exame> getExames() { return this.exames; } //... }

public class Exame implements Serializable { private Collection<Categoria> categorias; //... @ManyToMany public Collection<Categoria> getCategorias() { return this.categorias; } //... }
ok. Daí mais tarde eu tendo fazer:

categoria.getExames();
e vem vazio. Reparei que quando eu crio um exame dou um setCategoria, mas não o contrário, então acho que é por isso que ele não acha… está faltando algum anotação para ele se encontrar também no caminho inverso, qual seria? Acredito que seja o mappedBy em algum lugar aí, mas todas as tentativas que fiz foram frustradas (nunca entendi direito como funciona esse mappedBy).

Olá!

A anotação @ManyToMany e @OneToMany vc deve colocar em cima do atributo e não do método.

ficaria assim:

public class Exame implements Serializable { @ManyToMany(mappedBy = "exames") private Collection<Categoria> categorias; }

@Entity public class Categoria implements Serializable { @Id private Long id; @ManyToMany private Collection<Exame> exames; }

Tanto faz no atributo ou no getter, ambos funcionam igual.

Olá.

O mappedBy deve conter uma string com o nome da referência que aponta para a instância da entidade relacionada.
Exemplo:

[code]class Vendedor {
@OneToMany(mappedBy = “vendedor”)
private Collection<Venda> vendas;
}

class Venda {
// Observe o nome da variável: se o nome fosse xpto, na outra classe ficaria mappedBy = “xpto”
@ManyToOne
private Vendedor vendedor;
}[/code]Mas onde colocar o mappedBy?

No caso de relacionamentos um-para-muitos / muitos-para-um, é fácil: o mappedBy fica sempre na anotação @OneToMany.
No caso de relacionamentos um-para-um e muitos-para-muitos, é preciso identificar quem é o dono (owner) da associação. Dessa forma, você deve colocar o mappedBy sempre na entidade que não é a dona. Imagine um sistema acadêmico onde um professor dá aula em várias turmas, e cada turma pode ter vários professores (muitos para muitos). Supondo que o dono seja a classe Professor - um professor tem várias turmas - o mappedBy precisa ser colocado na entidade Turma.

[code]class Professor {
@ManyToMany
private Collection<Turma> turmas;
}

class Turma {
@ManyToMany(mappedBy = “turmas”)
private Collection<Professor> professores;
}[/code]Finalizando, você só precisa usar o mappedBy se sua associação for bidirecional. Isto é, se voce mapear a associação em apenas uma das classes participantes, não é preciso usar o mappedBy.

Espero ter ajudado a esclarecer. Abraços.

Me ajudou a entender, obrigado :slight_smile:

Mas ainda assim não está funcionando no meu caso… :frowning: talvez por um lado ser OneToMany e outro ManyToMany ??

Nossa, nem tinha reparado nisso :smiley: Com certeza esse é o problema.

Você precisa definir qual é a cardinalidade existente entre Exame e Categoria. Se for muitos para muitos, você precisa colocar a anotação @ManyToMany em ambas as classes. Se for um para muitos, é preciso usar @OneToMany em uma e @ManyToOne na outra.

Bom dia!

Estou com dificuldades com mappedBy…

Pelo que entendi das respostas…o mappedBy é usado apenas quando a associação é bidirecional; a anotação mappedBy deve estar na entidade que não é a “dona” no caso de many-to-many; e no caso de one-to-many e many-to-one sempre na entidade que possui a anotação one-to-many;

É isso certo?Ok…

Mas afinal, pra que serve o mappedBy?Ainda não entendi direito eu acho…Tem alguma interferencia no código quando se esta persistindo ou recuperando objetos?

Sobre bidirecional e unidirecional também me confunde um pouco.

Todos os tipos de associações one-to-one, one-to-many, many-to-one e many-to-many podem ser tanto unidirecional como bidirecional?

Pra ser unidirecional basta mapear apenas uma das entidades?

O motivo para usar uma associação bidirecional é quando uma entidade precisa saber da outra é isso ?

Ultima pergunta :oops: Em uma associação unidirecional many-to-many, as duas entidade devem possuir um array uma da outra? Mesmo se só um lado da associação é mapeado?

Obrigado, espero não ter forçado a barra :roll:

t+

Olá,

Isso.

O mappedBy informa ao framework que aquela coleção está relacionada ao campo que foi mapeado. Além de nortear o framework, essa informação é usada para criar a chave estrangeira. De que tipo de interferência você está falando?[/quote]

[quote=Filipe A.]Sobre bidirecional e unidirecional também me confunde um pouco.
Todos os tipos de associações one-to-one, one-to-many, many-to-one e many-to-many podem ser tanto unidirecional como bidirecional?
Pra ser unidirecional basta mapear apenas uma das entidades?[/quote]
Sim e sim. Mas sempre um dos lados é o dono do relacionamento (o que não usa o mappedBy).

Quando vc precisa obter os objetos que a entidade está recionada, não os que ela tem (que é dona), mas os objetos que a tem (que a usam).

Quem tem a coleção é obrigatoriamente o lado que é dono do relacionamento. No lado fraco da relação a utilização da coleção é opcional, sendo que se for usado, existe a necessidade de usar o mappedBy, senão são criadas duas tabelas que vão fazer as vezes das entidades associativas.

[]´s

A grosso modo o mappedBy diz ao framework por qual coluna ele ira fazer o link entre as tabelas no banco…

Olá davidbuzatto,

Obrigado pelas respostas…sobre a interferencia eu falo na hora de programar, mas acho que to viajando :roll:

Eu criei um programa aqui com relacionamento many-to-many veja só:

@ManyToMany(fetch = FetchType.LAZY, mappedBy = "materias", cascade = CascadeType.ALL)
	//@JoinTable(name = "materia_curso", joinColumns = @JoinColumn(name = "materia_id"), inverseJoinColumns = @JoinColumn(name = "curso_id"))
	public Set<Curso> getCursos() {
		return cursos;
	}
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name = "materia_curso", joinColumns = @JoinColumn(name = "curso_id"), inverseJoinColumns = @JoinColumn(name = "materia_id"))
	public Set<Materia> getMaterias() {
		return materias;
	}

Saberia me dizer porque eu tive que tirar a anotação:

 //@JoinTable(name = "materia_curso", joinColumns = @JoinColumn(name = "materia_id"), inverseJoinColumns = @JoinColumn(name = "curso_id"))

da tabela que não é a dona da associação “Materia” pra poder funcionar? Pois, se eu deixasse essa anotação dava erro…Poderia me explicar?

Obrigado!
t+