JPA&休眠-带外键的复合主键 [英] JPA & Hibernate - Composite primary key with foreign key

查看:62
本文介绍了JPA&休眠-带外键的复合主键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我想在Spring内存中有两个要查询的表.我已经成功地在名为Medicine的实体中对"Drugs"表进行了建模,但是现在需要对"drugInteraction"表进行建模-该表将具有drug_id(在Medicine表中称为id的PK)和drugInteraction中的drug_name的组合表,作为组合的主键.

So I have two tables which I would like to have in Spring memory to query. I have successfully managed to model the 'Drugs' table in an entiry called Medicine, however now need to model the 'drugInteraction' table - which will have the combination of drug_id(PK called id in medicine table), and the drug_name in the drugInteraction table, as a combined primary key.

在python中使用的架构:

Schemas as used in python:

cursor.execute("CREATE TABLE drugs(id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255), description TEXT, toxicity TEXT)")


cursor.execute("CREATE TABLE drugInteractions (drug_id INT NOT NULL, name VARCHAR(90), description TEXT, PRIMARY KEY(drug_id, name), FOREIGN KEY (drug_id) REFERENCES drugs (id))")

drugInteractions表的一些示例数据:

Some example data for the drugInteractions table:


drug_id     name       description

1       "Abciximab"         "The risk or severity of bleeding can be increased when Abciximab is combined with Lepirudin."
1       "Aceclofenac"        "The risk or severity of bleeding and hemorrhage can be increased when Aceclofenac is combined with Lepirudin."
1.      "Acemetacin"         "The risk or severity of bleeding and hemorrhage can be increased when Lepirudin is combined with Acemetacin."

drugs表的一些示例数据:

Some example data for the drugs table:

id.       name.       description

1       "Lepirudin"      "Lepirudin is identical to...."
2       "Cetuximab"      "Cetuximab is an epidermal growth..."

这是我对Medicine.java的要求:

Here's what I have for the Medicine.java:

package com.example.configbackendspring;

import net.minidev.json.JSONObject;

import javax.persistence.*;

@Entity
@Table(name = "drugs")
public class Medicine {
    @Id
    @GeneratedValue
    @Column(name = "id")
    private Integer id;
    @Column(name = "name")
    private String name;
    @Column(name = "description")
    private String description;
    @Column(name = "toxicity")
    private String toxicity;

    public Medicine(int id, String name, String description, String toxicity) {
        this.id=id;
        this.name=name;
        this.description=description;
        this.toxicity=toxicity;
    }


    public Medicine(){}


    public int getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getToxicity() {
        return toxicity;
    }

    public void setToxicity(String toxicity) {
        this.toxicity = toxicity;
    }

    public JSONObject toJSONObject(){
        JSONObject object = new JSONObject();
        JSONObject medicineObject = new JSONObject();
        medicineObject.appendField("name", this.name);
        medicineObject.appendField("description", this.description);
        medicineObject.appendField("toxicity", this.toxicity);
        medicineObject.appendField("id", this.id);
        object.appendField("medicine", medicineObject);
        return object;

    }
}

这就是我对drugInteraction.java所拥有的...不起作用

And this is what I have for the drugInteraction.java ...which does not work

package com.example.configbackendspring;

import net.minidev.json.JSONObject;

import javax.persistence.*;
import javax.resource.cci.Interaction;
import java.io.Serializable;


@Entity
@Table(name = "drugInteractions")
public class DrugInteraction {


    @EmbeddedId
    private InteractionId interactionId;

    @Column(name = "description")
    private String description;


    public DrugInteraction(int drug_id, String name, String description) {
        this.interactionId.drug_name = name;
        this.interactionId.drug_id = drug_id;
        this.description=description;

    }


    public DrugInteraction(){}


    public Integer getId() {
        return interactionId.drug_id;
    }


    public String getName() {
        return interactionId.drug_name;
    }


    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }


    public JSONObject toJSONObject(){
        JSONObject object = new JSONObject();
        JSONObject interactionObject = new JSONObject();
        interactionObject.appendField("name", interactionId.drug_name);
        interactionObject.appendField("description", this.description);
        interactionObject.appendField("drug_id", interactionId.drug_id);
        object.appendField("drugInteraction", interactionObject);
        return object;

    }
}

这是InteractionId.java

This is InteractionId.java

package com.example.configbackendspring;

import lombok.*;

import java.io.Serializable;

@RequiredArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@ToString
@EqualsAndHashCode
public class InteractionId implements Serializable
{

//    public InteractionId(int drug_id, String drug_name){
//        this.drug_id=drug_id;
//        this.drug_name=drug_name;
//
//    }


    @NonNull
    public int drug_id;

    @NonNull
    public String drug_name;
}


我当前的问题是我无法弄清楚如何将药物中的外键ID与复合键关联起来.上面的代码正在编译,但是数据库为空,因此导入必定会在某处失败

My current issue is that I can't figure out how to link the foreign key id in drugs with the composite key. The above code is compiling but the database is empty so the import must be failing somewhere

请,有人可以建议我如何更改文件以模拟上述行为吗?我在弄清楚如何使用外键对复合ID建模时遇到了麻烦

Please, can someone advise as to how I would change the files to model the above behaviour? I am having trouble figuring out how I would model the composite ID with foreign key

推荐答案

您有很多错误.如果您使用的是 @EmbeddedId ,则您的ID类必须是可嵌入的.

You have multiple things wrong. If you are using @EmbeddedId then the you ID class needs to be an embeddable.

@Embeddable
public class InteractionId {
    @Column(name="name")
    String name;
    Long drugId; //type should be same as for ID field on Medicine

    //equals and hashcode etc.
}

您还需要从 DrugInteraction 到以 MapsId 注释的 Medicine 之间的关系:

You also need a relationship from DrugInteraction to Medicine annotated with MapsId:

@Entity
@Table(name = "drugInteractions")
public class DrugInteraction {

    @EmbeddedId
    private InteractionId interactionId;

    @MapsId("drugId")//value corresponds to property in the ID class
    @ManyToOne
    @JoinColumn(name = "drug_id")
    private Medicine medicine;
}

要保存新实例:

DrugInteraction di = new DrugInteraction();
Medicine medicine = //an existing medicine
di.setName("Some Name");
di.setMedicine(medicine);
//save

或者,也可以使用 IDClass 而不是 EmbeddedId :

As an alternative, can also do this using an IDClass rather than EmbeddedId:

//not an embeddable
public class InteractionId {
    String name;
    Long drugId; //type should be same as for ID field on Medicine

    //equals and hashcode etc.
}

并更改映射:

@Entity
@Table(name = "drugInteractions")
@IdClass(InteractionId.class) //specify the ID class
public class DrugInteraction {

    @Id
    private String name;

    @Id
    @ManyToOne
    @JoinColumn(name = "drug_id")
    private Medicine medicine;
}

这篇关于JPA&休眠-带外键的复合主键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆