Nesse caso, você usa a @JoinTable
anotação JPA ?
fonte
Nesse caso, você usa a @JoinTable
anotação JPA ?
EDIT 2017-04-29 : Como apontado por alguns dos comentaristas, o JoinTable
exemplo não precisa do mappedBy
atributo de anotação. De fato, as versões recentes do Hibernate se recusam a iniciar, imprimindo o seguinte erro:
org.hibernate.AnnotationException:
Associations marked as mappedBy must not define database mappings
like @JoinTable or @JoinColumn
Vamos fingir que você tem uma entidade chamada Project
e outra entidade chamadaTask
e cada projeto pode ter muitas tarefas.
Você pode projetar o esquema do banco de dados para este cenário de duas maneiras.
A primeira solução é criar uma tabela denominada Project
e outra tabela denominada Task
e adicionar uma coluna de chave estrangeira à tabela de tarefas denominada project_id
:
Project Task
------- ----
id id
name name
project_id
Dessa forma, será possível determinar o projeto para cada linha na tabela de tarefas. Se você usar essa abordagem, em suas classes de entidade, não precisará de uma tabela de junção:
@Entity
public class Project {
@OneToMany(mappedBy = "project")
private Collection<Task> tasks;
}
@Entity
public class Task {
@ManyToOne
private Project project;
}
A outra solução é usar uma terceira tabela, por exemplo Project_Tasks
, e armazenar o relacionamento entre projetos e tarefas nessa tabela:
Project Task Project_Tasks
------- ---- -------------
id id project_id
name name task_id
A Project_Tasks
tabela é chamada "Tabela de junção". Para implementar esta segunda solução no JPA, você precisa usar a @JoinTable
anotação. Por exemplo, para implementar uma associação unidirecional um para muitos, podemos definir nossas entidades da seguinte forma:
Project
entidade:
@Entity
public class Project {
@Id
@GeneratedValue
private Long pid;
private String name;
@JoinTable
@OneToMany
private List<Task> tasks;
public Long getPid() {
return pid;
}
public void setPid(Long pid) {
this.pid = pid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Task> getTasks() {
return tasks;
}
public void setTasks(List<Task> tasks) {
this.tasks = tasks;
}
}
Task
entidade:
@Entity
public class Task {
@Id
@GeneratedValue
private Long tid;
private String name;
public Long getTid() {
return tid;
}
public void setTid(Long tid) {
this.tid = tid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Isso criará a seguinte estrutura de banco de dados:
A @JoinTable
anotação também permite personalizar vários aspectos da tabela de junção. Por exemplo, se tivéssemos anotado a tasks
propriedade assim:
@JoinTable(
name = "MY_JT",
joinColumns = @JoinColumn(
name = "PROJ_ID",
referencedColumnName = "PID"
),
inverseJoinColumns = @JoinColumn(
name = "TASK_ID",
referencedColumnName = "TID"
)
)
@OneToMany
private List<Task> tasks;
O banco de dados resultante teria se tornado:
Por fim, se você deseja criar um esquema para uma associação muitos-para-muitos, o uso de uma tabela de junção é a única solução disponível.
@JoinTable/@JoinColumn
pode ser anotado no mesmo campo commappedBy
. Assim, o exemplo correcta deve ser manter omappedBy
naProject
, e mover o@JoinColumn
paraTask.project
(ou vice-versa)Project_Tasks
precisa doname
deTask
bem, que se torna três colunas:project_id
,task_id
,task_name
, como conseguir isso?Caused by: org.hibernate.AnnotationException: Associations marked as mappedBy must not define database mappings like @JoinTable or @JoinColumn:
Também é mais limpo de usar
@JoinTable
quando uma Entidade pode ser a criança em vários relacionamentos pai / filho com diferentes tipos de pais. Para acompanhar o exemplo de Behrang, imagine que uma Tarefa possa ser filha de Projeto, Pessoa, Departamento, Estudo e Processo.A
task
tabela deve ter 5nullable
campos de chave estrangeira? Eu acho que não...fonte
É a única solução para mapear uma associação ManyToMany: você precisa de uma tabela de junção entre as duas tabelas de entidades para mapear a associação.
Também é usado para associações OneToMany (geralmente unidirecionais) quando você não deseja adicionar uma chave estrangeira na tabela do lado muitos e, assim, mantê-lo independente do lado.
Pesquise @JoinTable na documentação do hibernate para obter explicações e exemplos.
fonte
Ele permite que você lide com o relacionamento Muitos para Muitos. Exemplo:
Ingressar na tabela permite criar um mapeamento usando:
irá criar uma tabela:
fonte
@ManyToMany
associaçõesNa maioria das vezes, você precisará usar a
@JoinTable
anotação para especificar o mapeamento de um relacionamento de tabela muitos para muitos:Portanto, supondo que você tenha as seguintes tabelas de banco de dados:
Na
Post
entidade, você mapeará esse relacionamento, assim:A
@JoinTable
anotação é usada para especificar o nome da tabela por meio doname
atributo, bem como a coluna Chave Externa que faz referência àpost
tabela (por exemplo,joinColumns
) e a coluna Chave Estrangeira napost_tag
tabela de links que faz referência àTag
entidade por meio doinverseJoinColumns
atributo.Unidirecional
@OneToMany
AssociaçõesAs
@OneToMany
associações unidirecionais , que carecem de@JoinColumn
mapeamento, se comportam como relacionamentos de tabela muitos para muitos, em vez de um para muitos.Portanto, supondo que você tenha os seguintes mapeamentos de entidade:
O Hibernate assumirá o seguinte esquema de banco de dados para o mapeamento de entidade acima:
Como já explicado, o
@OneToMany
mapeamento JPA unidirecional se comporta como uma associação muitos-para-muitos.Para personalizar a tabela de links, você também pode usar a
@JoinTable
anotação:E agora, a tabela de links será chamada
post_comment_ref
e as colunas Foreign Key serãopost_id
, para apost
tabela epost_comment_id
para apost_comment
tabela.fonte