mvc - spring java tutorial
AnotaciĆ³n JPA "@JoinTable" (4)
Es la única solución para mapear una asociación ManyToMany: necesita una tabla de unión entre las tablas de entidades para mapear la asociación.
También se usa para asociaciones de OneToMany (por lo general, unidireccionales), cuando no desea agregar una clave foránea en la tabla de muchos lados, y así mantenerla independiente de un lado.
Busque @JoinTable en la documentación de hibernación para obtener explicaciones y ejemplos.
¿En qué caso usas JPA @JoinTable
annotation?
También es más limpio utilizar @JoinTable
cuando una entidad puede ser el hijo en varias relaciones padre / hijo con diferentes tipos de padres. Para seguir con el ejemplo de Behrang, imagine que una Tarea puede ser hija del Proyecto, Persona, Departamento, Estudio y Proceso.
¿Debería la tabla de task
tener 5 campos de claves externas nullable
? Yo creo que no...
Te permite manejar la relación Muchos a Muchos. Ejemplo:
Table 1: post
post has following columns
____________________
| ID | DATE |
|_________|_________|
| | |
|_________|_________|
Table 2: user
user has the following columns:
____________________
| ID |NAME |
|_________|_________|
| | |
|_________|_________|
Unirse a la tabla le permite crear una asignación usando:
@JoinTable(
name="USER_POST",
joinColumns=@JoinColumn(name="USER_ID", referencedColumnName="ID"),
inverseJoinColumns=@JoinColumn(name="POST_ID", referencedColumnName="ID"))
creará una tabla:
____________________
| USER_ID| POST_ID |
|_________|_________|
| | |
|_________|_________|
EDITAR 2017-04-29 : como señalaron algunos de los comentaristas, el ejemplo de JoinTable
no necesita el mappedBy
anotación mappedBy
. De hecho, las versiones recientes de Hibernate se niegan a iniciarse imprimiendo el siguiente error:
org.hibernate.AnnotationException:
Associations marked as mappedBy must not define database mappings
like @JoinTable or @JoinColumn
Imaginemos que tiene una entidad llamada Project
y otra entidad llamada Task
y cada proyecto puede tener muchas tareas.
Puede diseñar el esquema de la base de datos para este escenario de dos maneras.
La primera solución es crear una tabla llamada Project
y otra tabla llamada Task
y agregar una columna de clave externa a la tabla de tareas denominada project_id
.
Project Task
------- ----
id id
name name
project_id
De esta forma, será posible determinar el proyecto para cada fila en la tabla de tareas. Si usa este enfoque, en las clases de entidad no necesitará una tabla de unión:
@Entity
public class Project {
@OneToMany(mappedBy = "project")
private Collection<Task> tasks;
}
@Entity
public class Task {
@ManyToOne
private Project project;
}
La otra solución es usar una tercera tabla, por ejemplo, Project_Tasks
, y almacenar la relación entre proyectos y tareas en esa tabla:
Project Task Project_Tasks
------- ---- -------------
id id project_id
name name task_id
La tabla Project_Tasks
se denomina "Join Table". Para implementar esta segunda solución en JPA necesita usar la anotación @JoinTable
. Por ejemplo, para implementar una asociación de uno a varios unidireccional, podemos definir nuestras entidades como tales:
Entidad del Project
:
@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;
}
}
Entidad de Task
:
@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;
}
}
Esto creará la siguiente estructura de base de datos:
La anotación @JoinTable
también le permite personalizar diversos aspectos de la tabla de unión. Por ejemplo, si hubiéramos anotado las propiedades de tasks
como esta:
@JoinTable(
name = "MY_JT",
joinColumns = @JoinColumn(
name = "PROJ_ID",
referencedColumnName = "PID"
),
inverseJoinColumns = @JoinColumn(
name = "TASK_ID",
referencedColumnName = "TID"
)
)
@OneToMany
private List<Task> tasks;
La base de datos resultante se habría convertido en:
Finalmente, si desea crear un esquema para una asociación de muchos a muchos, usar una tabla de unión es la única solución disponible.