Sök…


Introduktion

En ManyToMany kartläggning beskriver ett förhållande mellan enheter där båda kan relateras till mer än en instans av varandra och definieras av @ManyToMany kommentaren.

Till skillnad från @OneToMany där en utländsk nyckelkolumn i enhetens tabell kan användas kräver ManyToMany en sammanfogningstabell som kartlägger enheterna till varandra.

parametrar

Anteckning Ändamål
@TableGenerator Definierar en primär nyckelgenerator som kan hänvisas till med namn när ett generatorelement anges för GeneratedValue
@GeneratedValue Tillhandahåller specifikation av generationsstrategier för värden på primära nycklar. Det kan tillämpas på en primär nyckelegenskap eller -fält för en enhet eller mappad superklass i samband med ID-annotationen.
@ManyToMany Anger förhållandet mellan anställda och projektenheter så att många anställda kan arbeta med flera projekt.
mappedBy="projects" Definierar ett dubbelriktat förhållande mellan anställd och projekt
@JoinColumn Anger namnet på kolumnen som kommer att hänvisa till enheten som ska anses vara föreningens ägare
@JoinTable Anger tabellen i databasen som håller anställda vid projektrelationer med utländska nycklar

Anmärkningar

  • @TableGenerator och @GeneratedValue används för automatisk ID-skapande med jpa-tabellgenerator.
  • @ManyToMany annotation anger förhållandet mellan anställda och projektenheter.
  • @JoinTable anger namnet på tabellen som ska användas som sammanfogningstabell jpa många till många kartläggningar mellan anställd och projekt med namn = “medarbetare_projekt”. Detta görs eftersom det inte finns något sätt att fastställa äganderätten till en jpa många till många kartläggning eftersom databastabellerna inte innehåller utländska nycklar för att hänvisa till andra tabeller.
  • @JoinColumn anger namnet på kolumnen som ska hänvisa till enheten som ska betraktas som ägare av föreningen medan @inverseJoinColumn anger namnet på den omvända sidan av relationen. (Du kan välja vilken sida som helst som ska betraktas som ägare. Se bara till att sidorna är i relation). I vårt fall har vi valt anställd som ägare så @JoinColumn hänvisar till kolumnen för arbetstagare i anslutningsbordet medarbetare_projekt och @InverseJoinColumn hänvisar till idprojekt som är omvänd sida av jpa många till många kartläggningar.
  • @ManyToMany annotation i Projektenhet visar omvänd relation, därför använder den mappedBy = projekt för att hänvisa till fältet i Anställd enhet.

Fullständigt exempel kan hänvisas här

Anställd för att projektera många till många kartläggningar

Arbetstagare.

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

}

Projektenhet:

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

}

Testkod

/ * Skapa 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();

Hur man hanterar sammansatt nyckel utan inbäddad kommentar

Om du har

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


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

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

I ovanstående scenario har rightrole sammansatt nyckel och för att få åtkomst till den i JPA måste användaren skapa en enhet med Embeddable kommentar.

Så här:

Enheten för höjdbordet är:

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

   .....

}

Inbäddbar kommentar är bra för enstaka objekt men det kommer att ge ett problem när du sätter in massposter.

Problemet är när användaren vill skapa ny role med rights sedan första användaren måste store(persist) role objekt och sedan användaren måste göra flush för att få nyligen genererade id för rollen. då och då kan användaren sätta det i rightrole enhetens objekt.

För att lösa den här användaren kan skriva enhet något annorlunda sätt.

Enhet för rolltabellen är:

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

@JoinTable-anteckningen kommer att ta hand om att infoga i rightrole även utan en enhet (så länge tabellen bara har ID-kolumnerna för roll och rätt).

Användaren kan då enkelt:

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);

Du måste skriva @ManyToMany (cascade = {CascadeType.PERSIST}) i inverseJoinColumner annars kommer dina förälderdata att raderas om barn raderas.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow