Hibernate:ManyToMany有额外的列没有创建关联

时间:2014-02-27 10:14:27

标签: java eclipse hibernate jpa

我正在关注指南,以便在我的两个类 Doctor 之间创建多对多关联。我希望关联的表有额外的列,所以我需要根据教程执行以下步骤。

http://www.mkyong.com/hibernate/hibernate-many-to-many-example-join-table-extra-column-annotation/

但是,现在当我运行代码来创建关联时,数据库中没有创建任何内容。

这是我的代码

医生

package edu.cs157b.hibernate;

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

import javax.persistence.*;

@Entity
@Table(name="DOCTOR_INFO")
@NamedQueries (
    {
        @NamedQuery(name = "Doctor.getAll", query = "from Doctor"),
        @NamedQuery(name = "Doctor.findByName", query = "from Doctor where name = :name")
    }
)
public class Doctor implements Person {

    private int id;
    private String name;
    private Specialty specialty;
    private List<AppointmentRequest> appointmentRequests = new ArrayList<AppointmentRequest>();

    @Id
    @GeneratedValue
    public int getId() {
        return id;
    }

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

    @Column(unique=true)
    public String getName() {
        return name;
    }

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

    @ManyToOne (fetch = FetchType.EAGER, cascade= CascadeType.PERSIST) 
    @JoinColumn(name="specialty_id") 
    public Specialty getSpecialty() {
        return specialty;
    }

    public void setSpecialty(Specialty specialty) {
        this.specialty = specialty;
    }

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "pk.doctor")
    public List<AppointmentRequest> getAppointmentRequests() {
        return this.appointmentRequests;
    }

    public void setAppointmentRequests(List<AppointmentRequest> appointmentRequests) {
        this.appointmentRequests = appointmentRequests;
    }

    @Transient
    public List<Patient> getPatients() {
        List<Patient> patients = new ArrayList<Patient>();

        for(AppointmentRequest appointment:appointmentRequests) {
            patients.add(appointment.getPatient());
        }
        return patients;
    }
}

病人

package edu.cs157b.hibernate;

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

import javax.persistence.*;

@Entity
@Table(name="PATIENT_INFO")
@NamedQueries (
    {
        @NamedQuery(name = "Patient.getAll", query = "from Patient"),
        @NamedQuery(name = "Patient.findByName", query = "from Patient where name = :name")
    }
)
public class Patient implements Person {

    private int id;
    private String name;
    private String medical_record;
    private List<AppointmentRequest> appointmentRequests = new ArrayList<AppointmentRequest>();

    public String getMedical_record() {
        return medical_record;
    }

    public void setMedical_record(String medical_record) {
        this.medical_record = medical_record;
    }

    @Id
    @GeneratedValue
    public int getId() {
        return id;
    }

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

    @Column(unique=true)
    public String getName() {
        return name;
    }

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

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "pk.patient", cascade=CascadeType.ALL)
    public List<AppointmentRequest> getAppointmentRequests() {
        return this.appointmentRequests;
    }

    public void setAppointmentRequests(List<AppointmentRequest> appointmentRequests) {
        this.appointmentRequests = appointmentRequests;
    }

    @Transient
    public List<Doctor> getDoctors() {
        List<Doctor> doctors = new ArrayList<Doctor>();

        for(AppointmentRequest appointment:appointmentRequests) {
            doctors.add(appointment.getDoctor());
        }
        return doctors;
    }
}

AppointmentRequest

package edu.cs157b.hibernate;

import java.util.Date;

import javax.persistence.AssociationOverride;
import javax.persistence.AssociationOverrides;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

@Entity
@Table(name = "APPOINTMENT_REQUEST")
@AssociationOverrides({
        @AssociationOverride(name = "pk.patient", 
            joinColumns = @JoinColumn(name = "PATIENT_ID")),
        @AssociationOverride(name = "pk.doctor", 
            joinColumns = @JoinColumn(name = "DOCTOR_ID")) })
public class AppointmentRequest implements java.io.Serializable {

    private AppointmentRequestId pk = new AppointmentRequestId();
    private Date appointmentDate;
    private boolean fulfilled;

    public AppointmentRequest() {
    }

    @EmbeddedId
    public AppointmentRequestId getPk() {
        return pk;
    }

    public void setPk(AppointmentRequestId pk) {
        this.pk = pk;
    }

    @Transient
    public Patient getPatient() {
        return getPk().getPatient();
    }

    public void setPatient(Patient patient) {
        getPk().setPatient(patient);
    }

    @Transient
    public Doctor getDoctor() {
        return getPk().getDoctor();
    }

    public void setDoctor(Doctor doctor) {
        getPk().setDoctor(doctor);
    }

    @Temporal(TemporalType.DATE)
    @Column(name = "APPOINTMENT_DATE", nullable = false, length = 10)
    public Date getAppointmentDate() {
        return this.appointmentDate;
    }

    public void setAppointmentDate(Date appointmentDate) {
        this.appointmentDate = appointmentDate;
    }

    public boolean equals(Object o) {
        if (this == o)
            return true;
        if (o == null || getClass() != o.getClass())
            return false;

        AppointmentRequest that = (AppointmentRequest) o;

        if (getPk() != null ? !getPk().equals(that.getPk())
                : that.getPk() != null)
            return false;

        return true;
    }

    public boolean isFulfilled() {
        return fulfilled;
    }

    public void setFulfilled(boolean fulfilled) {
        this.fulfilled = fulfilled;
    }

    public int hashCode() {
        return (getPk() != null ? getPk().hashCode() : 0);
    }
}

AppointmentRequestId

package edu.cs157b.hibernate;

import javax.persistence.Embeddable;
import javax.persistence.ManyToOne;

@Embeddable
public class AppointmentRequestId implements java.io.Serializable {

    private Patient patient;
    private Doctor doctor;

    @ManyToOne
    public Patient getPatient() {
        return patient;
    }

    public void setPatient(Patient patient) {
        this.patient = patient;
    }

    @ManyToOne
    public Doctor getDoctor() {
        return doctor;
    }

    public void setDoctor(Doctor doctor) {
        this.doctor = doctor;
    }

    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        AppointmentRequestId that = (AppointmentRequestId) o;

        if (patient != null ? !patient.equals(that.patient) : that.patient != null) return false;
        if (doctor != null ? !doctor.equals(that.doctor) : that.doctor != null)
            return false;

        return true;
    }

    public int hashCode() {
        int result;
        result = (patient != null ? patient.hashCode() : 0);
        result = 31 * result + (doctor != null ? doctor.hashCode() : 0);
        return result;
    }

}

创建关联的代码

public AppointmentRequest createAppointment(Patient patient, Doctor doctor) {
    Session session = sessionFactory.openSession();
    AppointmentRequest appointment = new AppointmentRequest();
    try {
        session.beginTransaction();
        if(patient == null) {
            throw new NullPointerException();
        }
        if(doctor == null) {
            throw new NullPointerException();
        }

        appointment.setPatient(patient);
        appointment.setDoctor(doctor);
        appointment.setFulfilled(true);

        patient.getAppointmentRequests().add(appointment);
        doctor.getAppointmentRequests().add(appointment);

        session.save(appointment);
        session.getTransaction().commit();
    }
    finally {
            session.close();
    }
    return appointment;         
}

除了必须创建自己的自定义方法以获取患者 医生 <之外,还有更好的方式来访问多对多关系/ em>通过 AppointmentRequest 表。

1 个答案:

答案 0 :(得分:0)

我认为您需要将AppointmentRequest对象提升为实体并保存患者和医生对象(级联关联将在同一事务中保存约会请求)。 由于你没有挽救病人或医生,实际上并没有得救。

这是一个答案,清楚地解释了嵌入对象和实体之间的区别。

Why do we use @Embeddable In Hibernate

因为预约请求除了映射患者和医生之间的关联之外还带有其他信息,所以它应该是一个实体。