Annotation JPA "@JoinTable"

Dans quel cas utilisez-vous l'annotation JPA @JoinTable?

113
demandé sur Manuel Drieschmanns 2011-03-30 00:10:35

4 réponses

EDIT 2017-04-29 : comme indiqué par certains commentateurs, l'exemple JoinTable n'a pas besoin de l'attribut d'annotation mappedBy. En fait, les versions récentes D'Hibernate refusent de démarrer en imprimant l'erreur suivante:

org.hibernate.AnnotationException: 
   Associations marked as mappedBy must not define database mappings 
   like @JoinTable or @JoinColumn

Supposons que vous disposez d'une entité nommée Project et une autre entité nommée Task et chaque projet peut avoir de nombreuses tâches.

, Vous pouvez concevoir le schéma de base de données pour ce scénario de deux façons.

La première solution est de créez une table nommée Project et une autre table nommée Task et ajoutez une colonne de clé étrangère à la table de tâches nommée project_id:

Project      Task
-------      ----
id           id
name         name
             project_id

De cette façon, il sera possible de déterminer le projet pour chaque ligne de la table des tâches. Si vous utilisez cette approche, dans vos classes d'entités, vous n'aurez pas besoin d'une table de jointure:

@Entity
public class Project {

   @OneToMany(mappedBy = "project")
   private Collection<Task> tasks;

}

@Entity
public class Task {

   @ManyToOne
   private Project project;

}

L'autre solution consiste à utiliser une troisième table, par exemple Project_Tasks, et à stocker la relation entre les projets et les tâches dans cette table:

Project      Task      Project_Tasks
-------      ----      -------------
id           id        project_id
name         name      task_id

La table Project_Tasks est appelée une "table de jointure". Pour implémenter cette deuxième solution dans JPA, vous devez utiliser l'annotation @JoinTable. Par exemple, afin de mettre en œuvre une association un-à-plusieurs unidirectionnelle, nous pouvons définir nos entités comme telles:

Project entité:

@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 entité:

@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;
    }

}

Cela créera la structure de base de données suivante:

ER Diagramme 1

L'annotation @JoinTable vous permet également de personnaliser divers aspects de la table de jointure. Pour exemple, avions-nous annoté la propriété tasks comme ceci:

@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 données résultante serait devenue:

ER Diagramme 2

Enfin, si vous voulez créer un schéma pour une association plusieurs à plusieurs, l'utilisation d'une table de jointure est la seule solution disponible.

276
répondu Behrang 2017-10-10 00:55:40

C'est la seule solution pour mapper une association ManyToMany : vous avez besoin d'une table de jointure entre les tables to entities pour mapper l'association.

Il est également utilisé pour les associations OneToMany (généralement unidirectionnelles), lorsque vous ne voulez pas ajouter de clé étrangère dans la table du côté many, et donc la garder indépendante du côté one.

Recherchez @JoinTable dans la documentation hibernate pour des explications et des exemples.

13
répondu JB Nizet 2011-03-29 21:08:45

Il est également plus propre d'utiliser @JoinTable lorsqu'une entité peut être l'enfant dans plusieurs relations parent / enfant avec différents types de parents. pour suivre l'exemple de Behrang, imaginez qu'une tâche peut être l'enfant du projet, de la personne, du Département, de L'étude et du processus.

La table task devrait-elle avoir 5 nullable champs de clé étrangère? Je ne pense pas...

13
répondu HDave 2014-01-02 15:24:34

Il vous permet de gérer plusieurs à plusieurs relations. Exemple:

Table 1: post

post has following columns
____________________
|  ID     |  DATE   |
|_________|_________|
|         |         |
|_________|_________|

Table 2: user

user has the following columns:

____________________
|     ID  |NAME     |
|_________|_________|
|         |         |
|_________|_________|

Join Table vous permet de créer un mappage en utilisant:

@JoinTable(
  name="USER_POST",
  joinColumns=@JoinColumn(name="USER_ID", referencedColumnName="ID"),
  inverseJoinColumns=@JoinColumn(name="POST_ID", referencedColumnName="ID"))

Va créer une table:

____________________
|  USER_ID| POST_ID |
|_________|_________|
|         |         |
|_________|_________|
3
répondu slal 2017-06-02 15:36:42