Spring 多对多删除对象

Spring ManyToMany delete object

我目前卡在 Spring 的某个点上。目前,我有 2 个 table,名为 Patient 和 Risk,还有一个名为 Riskpatient 的 table。每当我尝试从 Patient 实例中删除 Risk 对象时,它似乎并没有从列表中删除该对象。这是设置:

package medicapp.models.impl;

import com.fasterxml.jackson.annotation.JsonIgnore;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.*;
import java.util.Date;
import java.util.List;


@Entity
@Table(name="patient")
public class Patient {

    @Id
    @GeneratedValue
    @Column(name="Id")
    private int id;
    @Column(name="NatNumber")
    private String nationalNumber;
    @Column(name="FirstName")
    private String firstName;
    @Column(name="LastName")
    private String lastName;
    @Column(name="Address")
    private String address;
    @ManyToOne(cascade = {CascadeType.ALL})
    @JoinColumn(name="birthplace")
    private Municipality birthPlace;
    @ManyToOne(cascade = {CascadeType.ALL})
    @JoinColumn(name="zipcode")
    private Municipality municipality;
    @ManyToOne(cascade = {CascadeType.ALL})
    @JoinColumn(name="healthinsuranceid")
    private HealthInsurance healthInsurance;

    @Column(name="Nationality")
    private String nationality;
    @Column(name="ContactName")
    private String contactName;
    @Column(name="ContactNumber")
    private String contactNumber;
    @Column(name="Phone")
    private String phone;
    @Column(name="Email")
    private String email;
    @Column(name="Gender")
    private Character gender;
    @Column(name="DateOfBirth")
    @Temporal(TemporalType.DATE)
    private Date birthDate;
    @Column(name="Smoker")
    private boolean smoker;


    @ManyToOne(cascade = {CascadeType.ALL})
    @JoinColumn(name="bloodgroupid")
    private BloodType bloodType;

    @ManyToOne(cascade = {CascadeType.ALL})
    @JoinColumn(name="juridicalid")
    private Juridical juridical;

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "allergypatient",
            joinColumns={@JoinColumn(name="PatientId")},
            inverseJoinColumns={@JoinColumn(name="AllergyId")}
    )
    @JsonIgnore
    private List<Allergy> allergies;

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "medicationpatient",
            joinColumns = @JoinColumn(name="PatientId"),
            inverseJoinColumns = @JoinColumn(name = "MedicationId")
    )
    @JsonIgnore
    private List<Medication> medications;

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "chronicdiseasepatient",
            joinColumns = @JoinColumn(name="PatientId"),
            inverseJoinColumns = @JoinColumn(name = "ChronicDiseaseId")
    )
    @JsonIgnore
    private List<Disease> diseases;

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "vaccinationpatient",
            joinColumns = @JoinColumn(name="PatientId"),
            inverseJoinColumns = @JoinColumn(name = "VaccinationId")
    )
    @JsonIgnore
    private List<Vaccination> vaccinations;


    @ManyToMany//set to eager to solve hibernate exception: collection is not associated with any session
    @JoinTable(name = "riskpatient",
            joinColumns = @JoinColumn(name="PatientId"),
            inverseJoinColumns = @JoinColumn(name = "RiskId")
    )

    private List<Risk> risks;

    @Column(name="lastwill")
    private boolean lastWill;

    /**
     * Default Constructor without parameters, this is required for using Hibernate
     */
    public Patient() {
    }

    /**
     * Constructor used to manually make a new patient with the minimal required values
     * @param firstName The first name of the patient
     * @param lastName The last name of the patient
     * @param address The address of the patient
     * @param municipality The municipality of the patient
     * @param birthDate The birthdate of the patient
     */
    public Patient(String firstName, String lastName, String address, Municipality municipality, Date birthDate) {
        this.firstName = firstName;
        this.address = address;
        this.municipality = municipality;
        this.lastName = lastName;
        this.lastName = lastName;
        this.birthDate = birthDate;
    }


    /**
     * Patient constructor that uses all the values retrieved from the e-ID
     * @param firstName The first name of the patient
     * @param lastName The last name of the patient
     * @param address The address of the patient
     * @param municipality The municipality of the patient
     * @param birthPlace The birthplace of the patient
     * @param nationalNumber The nationalnumber of the patient
     * @param nationality The nationality of the patient
     * @param gender The gender of the patient
     * @param birthDate The birthdate of the patient
     * @author Geert Peters
     */
    public Patient(String firstName, String lastName, String address, Municipality municipality, Municipality birthPlace, String nationalNumber, String nationality, char gender, Date birthDate) {
        this.address = address;
        this.birthDate = birthDate;
        this.birthPlace = birthPlace;
        this.firstName = firstName;
        this.gender = gender;
        this.lastName = lastName;
        this.nationality = nationality;
        this.nationalNumber = nationalNumber;
        this.municipality = municipality;

    }

    /**
     * @param allergy adds an allergy to a patient's file
     */
    public void addAllergy(Allergy allergy) {
        this.allergies.add(allergy);
    }

    /**
     * @param disease adds a disease to a patient's file
     */
    public void addDisease(Disease disease) {
        this.diseases.add(disease);
    }

    /**
     * @param medication adds a medication to a patient's file
     */
    public void addMedication(Medication medication) {
        this.medications.add(medication);
    }

    /**
     * @param vaccination adds a vaccination to a patient's file
     */
    public void addVaccination(Vaccination vaccination) {
        this.vaccinations.add(vaccination);
    }

    /**
     * @param medication removes a medication  from the list
     */
    public void removeMedication(Medication medication) {
        this.medications.remove(medication);
    }

    /**
     * Gets smoker.
     *
     * @return Value of smoker.
     */
    public boolean isSmoker() {
        return smoker;
    }

    /**
     * Gets birthPlace.
     *
     * @return Value of birthPlace.
     */
    public Municipality getBirthPlace() {
        return birthPlace;
    }

    /**
     * Sets new id.
     *
     * @param id New value of id.
     */
    public void setId(int id) {
        this.id = id;
    }

    /**
     * Sets new smoker.
     *
     * @param smoker New value of smoker.
     */
    public void setSmoker(boolean smoker) {
        this.smoker = smoker;
    }

    /**
     * Gets id.
     *
     * @return Value of id.
     */
    public int getId() {
        return id;
    }

    /**
     * Gets address.
     *
     * @return Value of address.
     */
    public String getAddress() {
        return address;
    }

    /**
     * Sets new lastName.
     *
     * @param lastName New value of lastName.
     */
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    /**
     * Gets gender.
     *
     * @return Value of gender.
     */
    public char getGender() {
        return gender;
    }

    /**
     * Gets nationalNumber.
     *
     * @return Value of nationalNumber.
     */
    public String getNationalNumber() {
        return nationalNumber;
    }



    /**
     * Gets firstName.
     *
     * @return Value of firstName.
     */
    public String getFirstName() {
        return firstName;
    }

    /**
     * Gets municipality.
     *
     * @return Value of municipality.
     */
    public Municipality getMunicipality() {
        return municipality;
    }

    /**
     * Sets new nationalNumber.
     *
     * @param nationalNumber New value of nationalNumber.
     */
    public void setNationalNumber(String nationalNumber) {
        this.nationalNumber = nationalNumber;
    }

    /**
     * Sets new nationality.
     *
     * @param nationality New value of nationality.
     */
    public void setNationality(String nationality) {
        this.nationality = nationality;
    }

    /**
     * Sets new municipality.
     *
     * @param municipality New value of municipality.
     */
    public void setMunicipality(Municipality municipality) {
        this.municipality = municipality;
    }

    /**
     * Gets phone.
     *
     * @return Value of phone.
     */
    public String getPhone() {
        return phone;
    }

    /**
     * Sets new gender.
     *
     * @param gender New value of gender.
     */
    public void setGender(char gender) {
        this.gender = gender;
    }

    /**
     * Gets contactNumber.
     *
     * @return Value of contactNumber.
     */
    public String getContactNumber() {
        return contactNumber;
    }

    /**
     * Gets lastName.
     *
     * @return Value of lastName.
     */
    public String getLastName() {
        return lastName;
    }

    /**
     * Sets new address.
     *
     * @param address New value of address.
     */
    public void setAddress(String address) {
        this.address = address;
    }

    /**
     * Sets new firstName.
     *
     * @param firstName New value of firstName.
     */
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    /**
     * Sets new birthPlace.
     *
     * @param birthPlace New value of birthPlace.
     */
    public void setBirthPlace(Municipality birthPlace) {
        this.birthPlace = birthPlace;
    }

    /**
     * Gets nationality.
     *
     * @return Value of nationality.
     */
    public String getNationality() {
        return nationality;
    }

    /**
     * Gets contactName.
     *
     * @return Value of contactName.
     */
    public String getContactName() {
        return contactName;
    }

    /**
     * Gets birthDate.
     *
     * @return Value of birthDate.
     */
    public Date getBirthDate() {
        return birthDate;
    }

    /**
     * Sets new contactName.
     *
     * @param contactName New value of contactName.
     */
    public void setContactName(String contactName) {
        this.contactName = contactName;
    }

    /**
     * Sets new phone.
     *
     * @param phone New value of phone.
     */
    public void setPhone(String phone) {
        this.phone = phone;
    }

    /**
     * Sets new contactNumber.
     *
     * @param contactNumber New value of contactNumber.
     */
    public void setContactNumber(String contactNumber) {
        this.contactNumber = contactNumber;
    }



    /**
     * Sets new birthDate.
     *
     * @param birthDate New value of birthDate.
     */
    public void setBirthDate(Date birthDate) {
        this.birthDate = birthDate;
    }

    /**
     * Gets vaccinations.
     *
     * @return Value of vaccinations.
     */
    public List<Vaccination> getVaccinations() {
        return vaccinations;
    }

    /**
     * Gets allergies.
     *
     * @return Value(Set) of allergies.
     */
    public List<Allergy> getAllergies() {
        return allergies;
    }

    /**
     * Gets diseases.
     *
     * @return Value(List) of diseases.
     */
    public List<Disease> getDiseases() {
        return diseases;
    }

    /**
     * Gets medications.
     *
     * @return Value(List) of medications.
     */
    public List<Medication> getMedications() {
        return medications;
    }

    /**
     * Gets bloodgroup.
     *
     * @return Value of bloodgroup.
     */
    public BloodType getBloodType() {
        return bloodType;
    }

    /**
     * Sets new bloodgroup.
     *
     * @param bloodType New value of bloodgroup.
     */
    public void setBloodType(BloodType bloodType) {
        this.bloodType = bloodType;
    }

    /**
     * Gets HealthInsurance.
     *
     * @return Value of HealthInsureance.
     */
    public HealthInsurance getHealthInsurance() {
        return healthInsurance;
    }

    /**
     * Sets new HealthInsurance.
     *
     * @param healthInsurance New value of HealthInsurance.
     */
    public void setHealthInsurance(HealthInsurance healthInsurance) {
        this.healthInsurance = healthInsurance;
    }


    /**
     * Gets email.
     *
     * @return Value of email.
     */
    public String getEmail() {
        return email;
    }

    /**
     * Sets new lastWill.
     *
     * @param lastWill New value of lastWill.
     */
    public void setLastWill(boolean lastWill) {
        this.lastWill = lastWill;
    }

    /**
     * Sets new juridical.
     *
     * @param juridical New value of juridical.
     */
    public void setJuridical(Juridical juridical) {
        this.juridical = juridical;
    }

    /**
     * Sets new allergies.
     *
     * @param allergies New value of allergies.
     */
    public void setAllergies(List<Allergy> allergies) {
        this.allergies = allergies;
    }

    /**
     * Sets new diseases.
     *
     * @param diseases New value of diseases.
     */
    public void setDiseases(List<Disease> diseases) {
        this.diseases = diseases;
    }

    /**
     * Gets lastWill.
     *
     * @return Value of lastWill.
     */
    public boolean isLastWill() {
        return lastWill;
    }

    /**
     * Gets juridical.
     *
     * @return Value of juridical.
     */
    public Juridical getJuridical() {
        return juridical;
    }

    /**
     * Sets new medications.
     *
     * @param medications New value of medications.
     */
    public void setMedications(List<Medication> medications) {
        this.medications = medications;
    }

    /**
     * Sets new email.
     *
     * @param email New value of email.
     */
    public void setEmail(String email) {
        this.email = email;
    }

    /**
     * Sets new vaccinations.
     *
     * @param vaccinations New value of vaccinations.
     */
    public void setVaccinations(List<Vaccination> vaccinations) {
        this.vaccinations = vaccinations;
    }

    /**
     * Sets new Risks
     * @param risks New value of risks
     */
    public void setRisks(List<Risk> risks) {
        this.risks = risks;
    }

    /**
     * Gets all the risks bound to the patient
     * @return a {@link java.util.List} instance containing all the risks of the patient
     */

    public List<Risk> getRisks() {
        return risks;
    }
}

package medicapp.models.impl;


import javax.persistence.*;
import java.util.List;


@Entity
@Table(name="risk")
public class Risk {

    @Id
    @GeneratedValue
    @Column(name="id")
    private int id;

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

   /** @ManyToMany(mappedBy = "risks")
    private List<Patient> patientList;*/

    public Risk() {

    }

    public Risk(String description) {
        this.description = description;
    }

    public int getId() {
        return id;
    }

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

    public String getDescription() {
        return description;
    }

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

XML:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <import resource="spring-database.xml"/>
    <import resource="spring-security.xml"/>

    <bean id="viewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver"
          p:prefix="/WEB-INF/jsp/"
          p:suffix=".jsp" />

    <bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>

    <bean id="emf"
          class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceUnitName" value="medicapp" />
        <property name="dataSource" ref="dataSource" />
        <property name="persistenceProvider">
            <bean class="org.hibernate.jpa.HibernatePersistenceProvider" />
        </property>

    </bean>

    <bean id="tm" class="org.springframework.orm.jpa.JpaTransactionManager" p:entityManagerFactory-ref="emf" p:jpaDialect-ref="jpaDialect"/>

    <tx:annotation-driven transaction-manager="tm"/>

    <context:component-scan base-package="medicapp.*" />

    <context:spring-configured />
    <context:annotation-config />

    <mvc:resources mapping="/resources/**" location="/resources/mytheme/" />
    <mvc:annotation-driven/>

</beans>

我的 DAO 实现文件:

@Override
    @Transactional
    public Patient deleteRiskOfPatient(Patient patient, Risk risk) {
        try {
            patient.getRisks().remove(risk);
           // em.flush();
            return patient;
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getStackTrace());
        }
        return null;
    }

调用DAO方法的控制器方法:

 @RequestMapping(method = RequestMethod.GET, value="/delete")
    @Transactional
    public void test() {
        Patient patient = medicappDAO.getPatientById(6);
        Hibernate.initialize(patient.getRisks());
        System.out.println( patient.getRisks().size());
        medicappDAO.deleteRiskOfPatient(medicappDAO.getPatientById(6), medicappDAO.getPatientById(6).getRisks().get(0));
        System.out.println( patient.getRisks().size());
    }

每当我 运行 使用单元测试并将回滚设置为 false 时,它​​确实会被删除,但每当我使用控制器去那里时,它实际上并没有删除它。我什至在 DAO 方法中打印出列表的大小,在删除之前它说 4,之后是 3,但是当我回到控制器中时,它不知何故又回到了 4。

感谢您对此提供任何帮助。

国王问好

根据您发布的代码判断,您没有使用 Patient 的托管实例。在托管实例上尝试相同的方法,只需在修改患者之前添加 patient = em.find(Patient.class, patient.getId())

还有一件事,如果 equals()hashcode()Risk 实体中实现,remove(risk) 将正常工作。可以肯定的是,您可以通过调用 risk = em.find(Risk.class, risk.getId()).

来确保它也是托管实体
patient = em.find(Patient.class, patient.getId());
risk = em.find(Risk.class, risk.getId());
patient.getRisks().remove(risk);
return patient;