Zoeken…


Invoering

Een toewijzing van ManyToMany beschrijft een relatie tussen entiteiten waarbij beide gerelateerd kunnen zijn aan meer dan één instantie van elkaar en wordt gedefinieerd door de annotatie @ManyToMany .

In tegenstelling tot @OneToMany waar een kolom met een externe sleutel in de tabel van de entiteit kan worden gebruikt, heeft ManyToMany een join-tabel nodig die de entiteiten aan elkaar ManyToMany .

parameters

aantekening Doel
@TableGenerator Definieert een primaire sleutelgenerator waarnaar naar de naam kan worden verwezen wanneer een generatorelement wordt opgegeven voor de annotatie GeneratedValue
@GeneratedValue Biedt de specificatie van generatiestrategieën voor de waarden van primaire sleutels. Het kan worden toegepast op een primaire sleuteleigenschap of veld van een entiteit of toegewezen superklasse in combinatie met de Id-annotatie.
@ManyToMany Hiermee geeft u de relatie op tussen werknemers- en projectentiteiten zodat veel werknemers aan meerdere projecten kunnen werken.
mappedBy="projects" Definieert een bidirectionele relatie tussen werknemer en project
@JoinColumn Specificeert de naam van de kolom die zal verwijzen naar de entiteit die als eigenaar van de associatie moet worden beschouwd
@JoinTable Hiermee geeft u de tabel in de database op waarin relaties tussen medewerkers worden vastgelegd met behulp van buitenlandse sleutels

Opmerkingen

  • @TableGenerator en @GeneratedValue worden gebruikt voor het automatisch maken van ID's met behulp van de jpa-tabelgenerator.
  • De annotatie @ManyToMany geeft de relatie tussen werknemers- en projectentiteiten aan.
  • @JoinTable specificeert de naam van de tabel die moet worden gebruikt als join-tabel jpa veel te veel toewijzingen tussen werknemer en project met name = "employee_project". Dit wordt gedaan omdat er geen manier is om het eigendom van een veel te veel jpa-toewijzing te bepalen, omdat de databasetabellen geen externe sleutels bevatten die verwijzen naar een andere tabel.
  • @JoinColumn geeft de naam aan van de kolom die verwijst naar de entiteit die als eigenaar van de associatie moet worden beschouwd, terwijl @inverseJoinColumn de naam van de omgekeerde kant van de relatie opgeeft. (U kunt elke kant kiezen die als eigenaar moet worden beschouwd. Zorg er alleen voor dat die kanten in relatie staan). In ons geval hebben we Werknemer als eigenaar gekozen, dus @JoinColumn verwijst naar de ID-medewerker-kolom in de join-tabel employee_project en @InverseJoinColumn verwijst naar het ID-project dat de omgekeerde kant is van jpa veel naar veel kaarten.
  • De annotatie @ManyToMany in de projectentiteit vertoont een omgekeerde relatie, daarom wordt mappedBy = projects gebruikt om te verwijzen naar het veld in de entiteit Werknemer.

Volledige voorbeeld kan worden verwezen hier

Werknemer naar project Veel tot veel in kaart brengen

Medewerker entiteit.

package com.thejavageek.jpa.entities;

import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.TableGenerator;

@Entity
public class Employee {

    @TableGenerator(name = "employee_gen", table = "id_gen", pkColumnName = "gen_name", valueColumnName = "gen_val", allocationSize = 100)
    @Id
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "employee_gen")
    private int idemployee;
    private String name;

    @ManyToMany(cascade = CascadeType.PERSIST)
    @JoinTable(name = "employee_project", joinColumns = @JoinColumn(name = "idemployee"), inverseJoinColumns = @JoinColumn(name = "idproject"))
    private List<Project> projects;

    public int getIdemployee() {
        return idemployee;
    }

    public void setIdemployee(int idemployee) {
        this.idemployee = idemployee;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Project> getProjects() {
        return projects;
    }

    public void setProjects(List<Project> projects) {
        this.projects = projects;
    }

}

Project entiteit:

package com.thejavageek.jpa.entities;

import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.TableGenerator;

@Entity
public class Project {

    @TableGenerator(name = "project_gen", allocationSize = 1, pkColumnName = "gen_name", valueColumnName = "gen_val", table = "id_gen")
    @Id
    @GeneratedValue(generator = "project_gen", strategy = GenerationType.TABLE)
    private int idproject;
    private String name;

    @ManyToMany(mappedBy = "projects", cascade = CascadeType.PERSIST)
    private List<Employee> employees;

    public int getIdproject() {
        return idproject;
    }

    public void setIdproject(int idproject) {
        this.idproject = idproject;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Employee> getEmployees() {
        return employees;
    }

    public void setEmployees(List<Employee> employees) {
        this.employees = employees;
    }

}

Testcode

/ * Create EntityManagerFactory * / EntityManagerFactory emf = Persistence .createEntityManagerFactory ("JPAExamples");

    /* Create EntityManager */
    EntityManager em = emf.createEntityManager();

    EntityTransaction transaction = em.getTransaction();

    transaction.begin();

    Employee prasad = new Employee();
    prasad.setName("prasad kharkar");

    Employee harish = new Employee();
    harish.setName("Harish taware");

    Project ceg = new Project();
    ceg.setName("CEG");

    Project gtt = new Project();
    gtt.setName("GTT");

    List<Project> projects = new ArrayList<Project>();
    projects.add(ceg);
    projects.add(gtt);

    List<Employee> employees = new ArrayList<Employee>();
    employees.add(prasad);
    employees.add(harish);

    ceg.setEmployees(employees);
    gtt.setEmployees(employees);

    prasad.setProjects(projects);
    harish.setProjects(projects);

    em.persist(prasad);

    transaction.commit();

Hoe samengestelde sleutel te verwerken zonder insluitbare annotatie

Als je hebt

Role:
+-----------------------------+
| roleId | name | discription |
+-----------------------------+


Rights:
+-----------------------------+
| rightId | name | discription|
+-----------------------------+

rightrole
+------------------+
| roleId | rightId | 
+------------------+

In bovenstaand scenario heeft de rightrole een samengestelde sleutel en om toegang te krijgen in JPA moet de gebruiker entiteit maken met Embeddable annotatie.

Soortgelijk:

Entiteit voor rechtentabel is:

    @Entity
    @Table(name = "rightrole")
    public class RightRole extends BaseEntity<RightRolePK> {
    
        private static final long serialVersionUID = 1L;
    
        @EmbeddedId
        protected RightRolePK rightRolePK;

    
        @JoinColumn(name = "roleID", referencedColumnName = "roleID", insertable = false, updatable = false)
        @ManyToOne(fetch = FetchType.LAZY)
        private Role role;
    
        @JoinColumn(name = "rightID", referencedColumnName = "rightID", insertable = false, updatable = false)
        @ManyToOne(fetch = FetchType.LAZY)
        private Right right;

        ......
     }


    @Embeddable
    public class RightRolePK implements Serializable {
    private static final long serialVersionUID = 1L;

      @Basic(optional = false)
      @NotNull
      @Column(nullable = false)
      private long roleID;

      @Basic(optional = false)
      @NotNull
      @Column(nullable = false)
     private long rightID;

   .....

}

Insluitbare annotatie is prima voor een enkel object, maar het geeft een probleem bij het invoegen van bulkrecords.

Het probleem is dat wanneer de gebruiker wil nieuwe creëren role met rights dan de eerste gebruiker hebt om store(persist) role object en vervolgens de gebruiker hoeft te doen flush om nieuw gegenereerde krijgen id voor de rol. en dan kan de gebruiker het in het object van de rightrole entiteit plaatsen.

Om deze gebruiker op te lossen kan entiteit iets anders schrijven.

Entiteit voor roltabel is:

@Entity
@Table(name = "role")
public class Role {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @NotNull
    @Column(nullable = false)
    private Long roleID;

    
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "role", fetch = FetchType.LAZY)
    private List<RightRole> rightRoleList;
 
    @ManyToMany(cascade = {CascadeType.PERSIST})
    @JoinTable(name = "rightrole",
            joinColumns = {
                @JoinColumn(name = "roleID", referencedColumnName = "ROLE_ID")},
            inverseJoinColumns = {
                @JoinColumn(name = "rightID", referencedColumnName = "RIGHT_ID")})
    private List<Right> rightList;
.......
}

De annotatie @JoinTable zorgt ervoor dat deze zelfs zonder een entiteit in de tabel met rightrole (zolang die tabel alleen de id-kolommen van rol en recht heeft).

Gebruiker kan dan eenvoudig:

Role role = new  Role();
List<Right> rightList = new ArrayList<>();
Right right1 = new Right();
Right right2 = new Right();
rightList.add(right1);
rightList.add(right2);
role.setRightList(rightList);

U moet @ManyToMany (cascade = {CascadeType.PERSIST}) in inverseJoinColumns schrijven, anders worden uw oudergegevens verwijderd als het kind wordt verwijderd.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow