JPA OneToMany使用来自不同表的列

huangapple go评论97阅读模式
英文:

JPA OneToMany using columns from different tables

问题

以下是您提供的内容的翻译部分:

我在我的关系型数据库中有以下表格。

制造商表:

CREATE TABLE manufacturer (
  id int(10) unsigned NOT NULL AUTO_INCREMENT,
  name varchar(100),
  code varchar(50)
);

产品表:

CREATE TABLE product (
  id int(10) unsigned NOT NULL AUTO_INCREMENT,
  manufacturer_id int(10),
  name varchar(100),
  revision_id int(10),
  CONSTRAINT product_man_fk FOREIGN KEY (manufacturer_id) REFERENCES manufacturer (id) ON DELETE CASCADE
);

修订表:

CREATE TABLE revision (
  id int(10),
  code varchar(50),
  CONSTRAINT revision_uq UNIQUE(id, code)
);

请注意,在“revision”表中,“id”不是主键(PK)也不是唯一列,只有“id”和“code”的组合是唯一的。

现在,就JPA而言,我需要在“Product”类中只有一个“Revision”(而不是它们的集合),并且我需要进行如下映射:

class Product {
...
    @ManyToOne
    @JoinColumn(name="manufacturer_id")
    private Manufacturer manufacturer;

    @ManyToOne
    @JoinColumns({
      @JoinColumn(name="revision_id", referencedColumnName="id"),
      @JoinColumn(name="manufacturer.code", referencedColumnName="code")
    })
    private Revision revision;
}

显然,这不起作用,因为“manufacturer.code”不是“product”表的列。是否有任何方法可以将另一个父实体的字段传递给不同的“@ManyToOne”注解以进行映射?

提前感谢。

英文:

I have the following tables in my relational DB.

 CREATE TABLE manufacturer (
  id int(10) unsigned NOT NULL AUTO_INCREMENT,
  name varchar(100),
  code varchar(50)
);
 CREATE TABLE product (
  id int(10) unsigned NOT NULL AUTO_INCREMENT,
  manufacturer_id int(10)
  name varchar(100),
  revision_id int(10)
  CONSTRAINT product_man_fk FOREIGN KEY (manufacturer_id) REFERENCES manufacturer (id) ON DELETE CASCADE
);
 CREATE TABLE revision (
  id int(10),
  code varchar(50),
  CONSTRAINT revision_uq UNIQUE(id, code)
);

Please note that id is not a PK nor a unique column in revision, only a combination of id and code is unique.

Now, in terms of JPA, I need to have only one Revision within the class Product (not a collection of them) and I need to map it as follows:

class Product {
...
    @ManyToOne
    @JoinColumn(name="manufacturer_id")
    private Manufacturer manufacturer;

    @ManyToOne
    @JoinColumns({
      @JoinColumn(name="revision_id", referencedColumnName="id"),
      @JoinColumn(name="manufacturer.code", referencedColumnName="code")
    })
    private Revision revision;
}

This doesn't work obviously, as manufacturer.code is not a column of table product.
Is there any way to somehow pass a field from another parent entity to a different @ManyToOne annotation for mapping?

Thanks in advance

答案1

得分: 1

在JPA中,你不能直接从一个实体引用另一个实体的关系映射注解中的字段。但是,你可以通过引入一个额外的映射实体来实现所需的映射。

  1. 创建一个新的映射实体(例如ProductRevisionMapping),表示ProductRevision之间的映射关系。这个实体将具有由product_id(对Product的外键)和revision_id(对Revision的外键)组成的复合主键。
@Entity
@Table(name = "product_revision_mapping")
public class ProductRevisionMapping implements Serializable {

    @Id
    @ManyToOne
    @JoinColumn(name = "product_id")
    private Product product;

    @Id
    @ManyToOne
    @JoinColumns({
        @JoinColumn(name = "revision_id", referencedColumnName = "id"),
        @JoinColumn(name = "revision_code", referencedColumnName = "code")
    })
    private Revision revision;
}
  1. 修改Product实体,使其与ProductRevisionMapping具有一对一的映射关系。
@Entity
@Table(name = "product")
public class Product {

    // ...

    @OneToOne(mappedBy = "product")
    private ProductRevisionMapping productRevisionMapping;


    public Revision getRevision() {
        if (productRevisionMapping != null) {
            return productRevisionMapping.getRevision();
        }
        return null;
    }

    public void setRevision(Revision revision) {
        if (productRevisionMapping == null) {
            productRevisionMapping = new ProductRevisionMapping();
            productRevisionMapping.setProduct(this);
        }
        productRevisionMapping.setRevision(revision);
    }
}

通过这种修改,你可以在ProductRevision之间建立一对一的关系,使用ProductRevisionMapping作为中介映射实体。

确保适当处理ProductRevision实体的保存和更新,以维护映射的一致性。

英文:

In JPA, you cannot directly reference a field from one entity to another entity's relationship mapping annotation. However, you can achieve the desired mapping by introducing an additional mapping entity.

  1. Create a new mapping entity (e.g. ProductRevisionMapping), which represents the mapping between Product and Revision. This entity will have a composite primary key consisting of product_id (foreign key to Product) and revision_id (foreign key to Revision).
@Entity
@Table(name = "product_revision_mapping")
public class ProductRevisionMapping implements Serializable {

    @Id
    @ManyToOne
    @JoinColumn(name = "product_id")
    private Product product;

    @Id
    @ManyToOne
    @JoinColumns({
        @JoinColumn(name = "revision_id", referencedColumnName = "id"),
        @JoinColumn(name = "revision_code", referencedColumnName = "code")
    })
    private Revision revision;
}
  1. Modify the Product entity to have a one-to-one mapping with ProductRevisionMapping.
@Entity
@Table(name = "product")
public class Product {

    // ...

    @OneToOne(mappedBy = "product")
    private ProductRevisionMapping productRevisionMapping;


    public Revision getRevision() {
        if (productRevisionMapping != null) {
            return productRevisionMapping.getRevision();
        }
        return null;
    }

    public void setRevision(Revision revision) {
        if (productRevisionMapping == null) {
            productRevisionMapping = new ProductRevisionMapping();
            productRevisionMapping.setProduct(this);
        }
        productRevisionMapping.setRevision(revision);
    }
}

With this modification, you can have a one-to-one relationship between Product and Revision, using the ProductRevisionMapping as an intermediary mapping entity.

> Make sure to handle the saving and updating of Product and Revision entities appropriately to maintain the consistency of the mapping.

huangapple
  • 本文由 发表于 2023年6月2日 03:22:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/76385078.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定