簡體   English   中英

jpa - 如何與 IdClass 創建多對多關系?

[英]jpa - How to create a many to many relationship with an IdClass?

我有 3 張表具有多對多關系

  • A (id, name, ....) 主鍵id
  • B (id, name, ....) 帶主鍵id
  • AB (id_a, id_b, date, ....) -沒有主鍵的關系表

我可以為休眠類建模,以便我使用IdClass而不是EmbeddedId解決方案(這樣我就可以避免使用級聯不必要的調用級別 - getId().getA())

PS 試圖混合這些解決方案,但它不起作用:
http://www.mkyong.com/hibernate/hibernate-many-to-many-example-join-table-extra-column-annotation/
如何使用 Hibernate 映射復合鍵?

在建立實體之間的關系時,
離我最近的牆和我的頭經常加入......(斯蒂芬)

這是實體 A 和 B 之間多對多關系的工作示例:

一個.java

import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;

@Entity
public class A {
    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE)
    @Column(name="id_a")
    private Integer id;

    private String name;

    @OneToMany(mappedBy="a",cascade=CascadeType.ALL, fetch=FetchType.LAZY)
    private List<AB> abAssociations = new ArrayList<>();

    // Getters and setters...
}

B.java

import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;

@Entity
public class B {
    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE)
    @Column(name = "id_b")
    private Integer id;

    private String name;

    @OneToMany(mappedBy = "b", cascade=CascadeType.ALL, fetch=FetchType.LAZY)
    private List<AB> abAssociations = new ArrayList<>();

    // Getters and setters...
}

AB.java

import java.util.Date;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.ManyToOne;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity
@IdClass(ABid.class)
public class AB {
    @Id
    @ManyToOne(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
    private A a;

    @Id
    @ManyToOne(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
    private B b;

    @Temporal(TemporalType.TIMESTAMP)
    private Date date;

    // Getters and setters...
}

ABid.java

import java.io.Serializable;

// The IdClass MUST implement Serializable and override #hashCode and #equals
public class ABid implements Serializable {

    private static final long serialVersionUID = -2834827403836993112L;

    private A a;
    private B b;

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((a == null) ? 0 : a.hashCode());
        result = prime * result + ((b == null) ? 0 : b.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        ABid other = (ABid) obj;
        if (a == null) {
            if (other.a != null)
                return false;
        } else if (!a.equals(other.a))
            return false;
        if (b == null) {
            if (other.b != null)
                return false;
        } else if (!b.equals(other.b))
            return false;
        return true;
    }
}

pom.xml

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>4.3.7.Final</version>
    </dependency>

示例代碼

import java.util.Date;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class Main {
    public static void main(String[] args) {
        // * Init entity manager
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("playground");

        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();

        // * Create two entities and persist them
        // We must persist the entities first alone before we build and flush their relation
        A a = new A();
        a.setName("foo");
        em.persist(a);

        B b = new B();
        b.setName("bar");
        em.persist(b);

        // * Build relationships between the two previous entities
        AB ab = new AB();
        ab.setA(a);
        ab.setB(b);
        ab.setDate(new Date());
        a.getAbAssociations().add(ab);
        b.getAbAssociations().add(ab);

        // * Flush our changements in the database
        em.getTransaction().commit();
        em.close();
        emf.close();
    }
}

這是 Hibernate 在 Postgresql 數據庫上創建的表的 sql 代碼。

CREATE TABLE a
(
  id_a integer NOT NULL,
  name character varying(255),
  CONSTRAINT a_pkey PRIMARY KEY (id_a)
)

CREATE TABLE b
(
  id_b integer NOT NULL,
  name character varying(255),
  CONSTRAINT b_pkey PRIMARY KEY (id_b)
)

CREATE TABLE ab
(
  date timestamp without time zone,
  b_id_b integer NOT NULL,
  a_id_a integer NOT NULL,
  CONSTRAINT ab_pkey PRIMARY KEY (a_id_a, b_id_b),
  CONSTRAINT fk_3exna7nsxvj1kv9i9pntmwlf1 FOREIGN KEY (a_id_a)
      REFERENCES a (id_a) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT fk_n3jrq53nr1elew4rytocopkbu FOREIGN KEY (b_id_b)
      REFERENCES b (id_b) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)

回應@valik的評論。

嘗試這個 :

@Entity
public class AB {
    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE)
    @Column(name = "id_ab")
    private Integer id;

    @ManyToOne(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
    private A a;

    @ManyToOne(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
    private B b;

    @Temporal(TemporalType.TIMESTAMP)
    private Date date;

    // Getters and setters...
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM