web-dev-qa-db-fra.com

Comment créer une table de jointure avec des annotations JPA?

Je dois créer une table de jointure dans ma base de données en utilisant les annotations JPA afin d'obtenir le résultat suivant:

enter image description here

Jusqu'à présent, je viens d'implémenter 2 entités:

@Entity
@Table(name="USERS", schema="ADMIN")
public class User implements Serializable {

    private static final long serialVersionUID = -1244856316278032177L;
    @Id 
    @Column(nullable = false)
    private String userid;  

    @Column(nullable = false)
    private String password;

    public String getUserid() {
        return userid;
    }

    public void setUserid(String userid) {
        this.userid = userid;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

}

@Entity
@Table(name="GROUPS", schema="ADMIN")
public class Group implements Serializable {

    private static final long serialVersionUID = -7274308564659753174L;
    @Id
    @Column(nullable = false)
    private String groupid;

    public String getGroupid() {
        return groupid;
    }
    public void setGroupid(String groupid) {
        this.groupid = groupid;
    }
}

Devrais-je créer une autre entité appelée USER_GROUP ou je peux simplement ajouter des annotations, de sorte que la table de jointure soit créée automatiquement lorsque j'exécute create tables from entity (ORM)?

Comment dois-je annoter mes entités pour obtenir le même résultat que dans l'image?

27
sfrj

Vous ne devriez certainement pas créer d'entité User_Group, car il s'agit davantage de la représentation de base de données sous-jacente que de celle orientée objet.

Vous pouvez atteindre la table de jointure en définissant quelque chose comme:

@Entity
@Table(name="USERS", schema="ADMIN")
public class User implements Serializable {
//...

@ManyToOne
@JoinTable(name="USER_GROUP")
Group group;

@Entity
@Table(name="GROUPS", schema="ADMIN")
public class Group implements Serializable {
//...

@OneToMany(mappedBy="group")
Set<User> users;

Edit: Si vous souhaitez définir explicitement les noms des colonnes, vous pouvez utiliser les éléments @JoinColumn comme indiqué ci-dessous:

@ManyToOne
@JoinTable(name="USER_GROUP",
    joinColumns = @JoinColumn(name = "userid", 
                              referencedColumnName = "userid"), 
    inverseJoinColumns = @JoinColumn(name = "groupid", 
                              referencedColumnName = "groupid"))
Group group;
35
Piotr Nowicki

Je le mettrais en œuvre de cette façon: 

@Entity
@Table(name="GROUPS", schema="ADMIN")
public class Group implements Serializable {
  @OneToMany
  @JoinTable(name = "USER_GROUP",
            joinColumns = @JoinColumn(name = "groupid"),
            inverseJoinColumns = @JoinColumn(name = "userid"))
  private List<User> users;
}

La solution suggérée par @PedroKowalski devrait également fonctionner, mais vous devrez alors garder une référence à Groupe entité dans votre Utilisateur entité, ce qui n'est pas toujours possible.

6
jFrenetic

Pour avoir les mêmes annotations que dans votre diagramme, vous pouvez le faire dans votre classe User:

@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "USER_GROUP", 
           joinColumns = { @JoinColumn(name = "userid") }, 
           inverseJoinColumns = { @JoinColumn(name = "groupid") })
private List<Group> grups;

dans votre classe de groupe

@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "USER_GROUP", 
           joinColumns = { @JoinColumn(name = "groupid") }, 
           inverseJoinColumns = { @JoinColumn(name = "userid") })
private List<User> users;
6
user902383

Je me demande quel est l’intérêt de créer une table de jointure de cette façon, étant donné que nous ne pouvons pas accéder directement aux requêtes? pour effectuer une opération sur USER_GROUP , il doit créer une requête de jointure normale entre utilisateurs et groupes ; pour cette raison, la table de jointure USER_GROUP est inutile.

1
Angel