JPA & Hibernate - составной первичный ключ с внешним ключом - PullRequest
0 голосов
/ 23 октября 2019

Итак, у меня есть две таблицы, которые я хотел бы иметь в памяти Spring для запроса. Мне удалось смоделировать таблицу «Drugs» в начальной точке под названием «Лекарство», однако теперь мне нужно смоделировать таблицу «drugInteraction», которая будет содержать комбинацию drug_id (PK называется id в таблице лекарств) и drug_name в drugInteraction. table, как объединенный первичный ключ.

Схемы, используемые в 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:


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."

Некоторые примеры данных длятаблица лекарств:

id.       name.       description

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

Вот что у меня есть для Лекарства. 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;

    }
}

И это то, что у меня есть для лекарства, Взаимодействие. Ява ... который не работает

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

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


Моя текущая проблема заключается в том, что я не могу понять, как связать идентификатор внешнего ключа в препаратах с составным ключом. Приведенный выше код компилируется, но база данных пуста, поэтому импорт должен произойти сбой где-то

Пожалуйста, кто-то может посоветовать, как мне изменить файлы для моделирования вышеупомянутого поведения? У меня возникают проблемы с выяснением того, как мне смоделировать составной идентификатор с внешним ключом

1 Ответ

1 голос
/ 23 октября 2019

У вас есть много неправильных вещей. Если вы используете @EmbeddedId, тогда класс you ID должен быть встраиваемым.

@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 до Medicine с комментариями 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:

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