Anotação da JPA "@JoinTable"
nesse caso, usa a anotação JPA @JoinTable
?
4 answers
EDIT 2017-04-29 : Como apontado por alguns dos comentaristas, o exemplo JoinTable
não precisa do atributo mappedBy
de anotação. Na verdade, as versões recentes do Hibernate recusam-se 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 tens uma entidade chamada
Project
e outra entidade chamada Task
e cada projecto pode ter muitas tarefas.
Você pode projetar o esquema da base de dados para este cenário de duas maneiras.
A primeira solução é: para criar uma tabela chamada Project
e outra tabela chamada Task
e adicionar uma coluna de chave estrangeira à tabela de tarefas chamada project_id
:
Project Task
------- ----
id id
name name
project_id
Deste modo, será possível determinar o projecto para cada linha da tabela de Tarefas. Se você usar esta abordagem, em suas classes de entidade você não precisará de uma tabela de adesã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 a relação entre projectos e tarefas nessa tabela:
Project Task Project_Tasks
------- ---- -------------
id id project_id
name name task_id
A tabela é chamado de "mesa de apoio". Para implementar esta segunda solução na App você precisa usar a anotação @JoinTable
. Por exemplo, para implementar uma associação Uni-direcional de um para muitos, podemos definir nossas entidades como tais:
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;
}
}
Isto irá criar a seguinte estrutura de base de Dados:
A anotação @JoinTable
também lhe permite personalizar vários aspectos da junção tabela. Por exemplo, se tivéssemos anotado a propriedade tasks
assim:
@JoinTable(
name = "MY_JT",
joinColumns = @JoinColumn(
name = "PROJ_ID",
referencedColumnName = "PID"
),
inverseJoinColumns = @JoinColumn(
name = "TASK_ID",
referencedColumnName = "TID"
)
)
@OneToMany
private List<Task> tasks;
A base de dados resultante tornar-se-ia:
Finalmente, se você quiser criar um esquema para uma associação de muitos para muitos, usar uma tabela de junção é a única solução disponível.
É a única solução para mapear uma associação ManyToMany: você precisa de uma tabela de junção entre as tabelas para Entidades para mapear a associação.
Também é usado para associações Onetomânicas (geralmente unidirecionais), quando você não quer adicionar uma chave estrangeira na tabela de muitos lados, e assim mantê-la independente de um lado.Procura por @JoinTable na documentação hibernar por explicações e exemplos.
Também é mais limpo usar {[[0]} quando uma entidade pode ser a criança em vários relacionamentos pais / filhos com diferentes tipos de Pais. para seguir o exemplo de Behrang, imagine uma tarefa pode ser o Filho do projeto, pessoa, Departamento, estudo e processo.
A Tabela task
deve ter 5 nullable
campos de chave estrangeiros? Acho que não...
Table 1: post
post has following columns
____________________
| ID | DATE |
|_________|_________|
| | |
|_________|_________|
Table 2: user
user has the following columns:
____________________
| ID |NAME |
|_________|_________|
| | |
|_________|_________|
Juntar A Tabela permite-lhe criar um mapeamento usando:
@JoinTable(
name="USER_POST",
joinColumns=@JoinColumn(name="USER_ID", referencedColumnName="ID"),
inverseJoinColumns=@JoinColumn(name="POST_ID", referencedColumnName="ID"))
Criará uma tabela:
____________________
| USER_ID| POST_ID |
|_________|_________|
| | |
|_________|_________|