首页 > 解决方案 > Json 中的 OneToOne 关系

问题描述

我创建了一个要发送到前端的 SecretData 对象:

package pl.portal.randkowy.model;

import com.fasterxml.jackson.annotation.JsonBackReference;

import javax.persistence.*;

import static javax.persistence.GenerationType.SEQUENCE;

@Entity(name = "SecretData")
@Table(
        name = "secret_data",
        uniqueConstraints = {
                @UniqueConstraint(
                        name = "secret_data_id_unique",
                        columnNames = "id")
        }
)
public class SecretData {

    @Id
    @SequenceGenerator(
            name = "secret_data_sequence",
            sequenceName = "secret_data_sequence",
            allocationSize = 1
    )
    @GeneratedValue(
            strategy = SEQUENCE,
            generator = "secret_data_sequence"
    )
    @Column(
            name = "id",
            updatable = false,
            unique = true
    )
    private Long id;

    @Column(
            name = "login",
            nullable = true,
            columnDefinition = "TEXT"
    )
    private String login;

    @Column(
            name = "password",
            nullable = true,
            columnDefinition = "TEXT"
    )
    private String password;

    @Column(
            name = "role",
            nullable = true,
            columnDefinition = "TEXT"
    )
    private String role;

    @Column(
            name = "private_email",
            nullable = true,
            columnDefinition = "TEXT"
    )
    private String privateEmail;

    //1-kierunkowa relacja
    @OneToOne(
            cascade = CascadeType.ALL,
            fetch = FetchType.EAGER, //domyślne
            orphanRemoval = true
    )
    @JoinColumn(
            name = "person_id", //nazwa kolumny w tabeli bazy danych
            referencedColumnName = "id", //nazwa pola z klasy Person po którym idzie relacja
            nullable = true,
            foreignKey = @ForeignKey(
                    name = "person_secret_data_fk"
            )
    )
    @JsonBackReference
    private Person person;

    public SecretData() {
    }

    public SecretData(String login, String password, String role, String privateEmail) {
        this.login = login;
        this.password = password;
        this.role = role;
        this.privateEmail = privateEmail;
    }

    public SecretData(String login, String password, String role, String privateEmail, Person person) {
        this.login = login;
        this.password = password;
        this.role = role;
        this.privateEmail = privateEmail;
        this.person = person;
    }

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }

    public Long getId() {
        return id;
    }

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

    public String getLogin() {
        return login;
    }

    public void setLogin(String login) {
        this.login = login;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }

    public String getPrivateEmail() {
        return privateEmail;
    }

    public void setPrivateEmail(String privateEmail) {
        this.privateEmail = privateEmail;
    }

    @Override
    public String toString() {
        return "SecretData{" +
                "id=" + id +
                ", login='" + login + '\'' +
                ", password='" + password + '\'' +
                ", role='" + role + '\'' +
                ", privateEmail='" + privateEmail + '\'' +
                '}';
    }
}

它与 Person 具有 OneToOne 关系

package pl.portal.randkowy.model;

import com.fasterxml.jackson.annotation.JsonManagedReference;

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

import static javax.persistence.GenerationType.SEQUENCE;

@Entity(name = "Person")
@Table(
        name = "persons",
        uniqueConstraints = {
                @UniqueConstraint(
                        name = "person_email_unique",
                        columnNames = "email")
        }
)
public class Person {

    @Id
    @SequenceGenerator(
            name = "person_sequence",
            sequenceName = "person_sequence",
            allocationSize = 1
    )
    @GeneratedValue(
            strategy = SEQUENCE,
            generator = "person_sequence"
    )
    @Column(
            name = "id",
            updatable = false
    )
    private Long id;

    @Column(
            name = "name",
            nullable = true,
            columnDefinition = "TEXT"
    )
    private String name;
    @Column(
            name = "last_name",
            nullable = true,
            columnDefinition = "TEXT"
    )
    private String lastName;
    @Column(
            name = "date_of_birth",
            nullable = true,
            columnDefinition = "DATE"
    )
    private Date dateOfBirth;
    @Column(
            name = "sex",
            nullable = true,
            columnDefinition = "TEXT"
    )
    private String sex;
    @Column(
            name = "sexual_orientation",
            nullable = true,
            columnDefinition = "TEXT"
    )
    private String sexualOrientation;
    @Column(
            name = "marital_status",
            nullable = true,
            columnDefinition = "TEXT"
    )
    private String maritalStatus;
    @Column(
            name = "province",
            nullable = true,
            columnDefinition = "TEXT"
    )
    private String province;
    @Column(
            name = "city",
            nullable = true,
            columnDefinition = "TEXT"
    )
    private String city;
    @Column(
            name = "self_description",
            nullable = true,
            columnDefinition = "TEXT"
    )
    private String selfDescription;
    @Column(
            name = "life_motto",
            nullable = true,
            columnDefinition = "TEXT"
    )
    private String lifeMotto;
    @Column(
            name = "thought_of_the_day",
            nullable = true,
            columnDefinition = "TEXT"
    )
    private String thoughtOfTheDay;
    @Column(
            name = "photo",
            nullable = true,
            columnDefinition = "TEXT"
    )
    private String photo;
    @Column(
            name = "profession",
            nullable = true,
            columnDefinition = "TEXT"
    )
    private String profession;
    @Column(
            name = "education",
            nullable = true,
            columnDefinition = "TEXT"
    )
    private String education;
    @Column(
            name = "email",
            nullable = true,
            columnDefinition = "TEXT"
    )
    private String email;

    //trzeba dodać, żeby z relacji 1-kierunkowej zrobić relacje 2-kierunkową
    @OneToOne(
            mappedBy = "person",
            orphanRemoval = false,
            cascade = {CascadeType.PERSIST, CascadeType.DETACH, CascadeType.MERGE}
    ) //pole po którym idzie relacja z klasy SecretData
    @JsonManagedReference
    private SecretData secretData;

    //trzeba dodać, żeby z relacji 1-kierunkowej zrobić relacje 2-kierunkową
    @OneToOne(
            mappedBy = "person",
            orphanRemoval = false,
            cascade = CascadeType.ALL
    ) //pole po którym idzie relacja z klasy Preference
    private Preference preference;


    //jeśli ma być 2-kierunkowa to też tutaj trzeba dodać poniższy wpis i metody poniżej
    @OneToMany(
            mappedBy = "person",
            orphanRemoval = true,
            cascade = CascadeType.ALL,
            fetch = FetchType.LAZY //domyślna wartość
    )
    private List<Proposition> propositions = new ArrayList<>();

    @OneToMany(
            mappedBy = "sender",
            orphanRemoval = true,
            cascade = CascadeType.ALL,
            fetch = FetchType.LAZY //domyślna wartość
    )
    private List<Email> emails = new ArrayList<>();


    @ManyToMany(
            cascade = {CascadeType.PERSIST, CascadeType.REMOVE}
    )
    @JoinTable(
            name = "person_interest",
            joinColumns = @JoinColumn(
                    name = "person_id",
                    foreignKey = @ForeignKey(name = "person_id_fk")
            ),
            inverseJoinColumns = @JoinColumn(
                    name = "interest_id",
                    foreignKey = @ForeignKey(name = "interest_id_fk")
            )
    )
    private List<Interest> interests = new ArrayList<>();

    public Person() {
    }

    public Person(String name, String lastName) {
        this.name = name;
        this.lastName = lastName;
    }

    public Person(String name, String lastName, Date dateOfBirth, String sex, String sexualOrientation, String maritalStatus, String province, String city, String selfDescription, String lifeMotto, String thoughtOfTheDay, String photo, String profession, String education, String email) {
        this.name = name;
        this.lastName = lastName;
        this.dateOfBirth = dateOfBirth;
        this.sex = sex;
        this.sexualOrientation = sexualOrientation;
        this.maritalStatus = maritalStatus;
        this.province = province;
        this.city = city;
        this.selfDescription = selfDescription;
        this.lifeMotto = lifeMotto;
        this.thoughtOfTheDay = thoughtOfTheDay;
        this.photo = photo;
        this.profession = profession;
        this.education = education;
        this.email = email;
    }

    public Long getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public Date getDateOfBirth() {
        return dateOfBirth;
    }

    public void setDateOfBirth(Date dateOfBirth) {
        this.dateOfBirth = dateOfBirth;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getSexualOrientation() {
        return sexualOrientation;
    }

    public void setSexualOrientation(String sexualOrientation) {
        this.sexualOrientation = sexualOrientation;
    }

    public String getMaritalStatus() {
        return maritalStatus;
    }

    public void setMaritalStatus(String maritalStatus) {
        this.maritalStatus = maritalStatus;
    }

    public String getProvince() {
        return province;
    }

    public void setProvince(String province) {
        this.province = province;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getSelfDescription() {
        return selfDescription;
    }

    public void setSelfDescription(String selfDescription) {
        this.selfDescription = selfDescription;
    }

    public String getLifeMotto() {
        return lifeMotto;
    }

    public void setLifeMotto(String lifeMotto) {
        this.lifeMotto = lifeMotto;
    }

    public String getThoughtOfTheDay() {
        return thoughtOfTheDay;
    }

    public void setThoughtOfTheDay(String thoughtOfTheDay) {
        this.thoughtOfTheDay = thoughtOfTheDay;
    }

    public String getPhoto() {
        return photo;
    }

    public void setPhoto(String photo) {
        this.photo = photo;
    }

    public String getProfession() {
        return profession;
    }

    public void setProfession(String profession) {
        this.profession = profession;
    }

    public String getEducation() {
        return education;
    }

    public void setEducation(String education) {
        this.education = education;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public List<Interest> getInterests() {
        return interests;
    }

    public void addInterest(Interest interest) {
        interests.add(interest);
        interest.getPersons().add(this);
    }

    public void removeInterest(Interest interest) {
        interests.remove(interest);
        interest.getPersons().remove(this);
    }


    public List<Proposition> getPropositions() {
        return propositions;
    }



    public void addProposition(Proposition proposition) {
        if (!this.propositions.contains(proposition)) {
            this.propositions.add(proposition);
            proposition.setPerson(this);
        }
    }

    public void addEmail(Email email) {
        if (!this.emails.contains(email)) {
            this.emails.add(email);
            email.setSender(this);
        }
    }

    public void removeProposition(Proposition proposition) {
        if (this.propositions.contains(proposition)) {
            this.propositions.remove(proposition);
            proposition.setPerson(null);
        }
    }

    public void removeEmail(Email email) {
        if (this.emails.contains(email)) {
            this.emails.remove(email);
            email.setSender(null);
        }
    }

    public void setSecretData(SecretData secretData) {
        this.secretData = secretData;
    }
    public SecretData getSecretData() {
        return secretData;
    }


    public Preference getPreference() {
        return preference;
    }

    public void setPreference(Preference preference) {
        preference.setPerson(this);
        this.preference = preference;

    }

    public void setPropositions(List<Proposition> propositions) {
        this.propositions = propositions;
    }

    public void setInterests(List<Interest> interests) {
        this.interests = interests;
    }

    public List<Email> getEmails() {
        return emails;
    }

    public void setEmails(List<Email> emails) {
        this.emails = emails;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", lastName='" + lastName + '\'' +
                ", dateOfBirth=" + dateOfBirth +
                ", sex='" + sex + '\'' +
                ", sexualOrientation='" + sexualOrientation + '\'' +
                ", maritalStatus='" + maritalStatus + '\'' +
                ", province='" + province + '\'' +
                ", city='" + city + '\'' +
                ", selfDescription='" + selfDescription + '\'' +
                ", lifeMotto='" + lifeMotto + '\'' +
                ", thoughtOfTheDay='" + thoughtOfTheDay + '\'' +
                ", photo='" + photo + '\'' +
                ", profession='" + profession + '\'' +
                ", education='" + education + '\'' +
                ", email='" + email + '\'' +
                ", secretData=" + secretData +
                ", preference=" + preference +
                ", propositions=" + propositions +
                ", emails=" + emails +
                ", interests=" + interests +
                '}';
    }



}

当我使用 Postman/Angular 通过 REST 获取数据时

控制器

@GetMapping("/all")
    public ResponseEntity <List<SecretData>> getAllSecretData(){
        List<SecretData> secretDataList = secretDataService.findAllSecretData();
        return new ResponseEntity<>(secretDataList, HttpStatus.OK);
    }

服务

public List<SecretData> findAllSecretData(){
        return secretDataRepository.findAll();
    }

我没有在 JSON 中获取 SecredData 中的 Person 对象。如何将此数据包含在发送的响应中?(第二个对象内的一个对象)。我现在正在尝试使用 DTO,但没有 DTO 它也不起作用。

标签: springspring-bootrestjpaspring-data

解决方案


您应该创建一个新类,该类应该代表您在响应中需要的输出格式。

表示输出格式的SecretDataOutput类

public class SecretDataOutput {
  private long id;
  private String login, password, role, privateEmail;

  private Person person;

  public SecretDataOutput(long id, String login, String password, String role, String privateEmail, Person person) {
    this.id = id;
    this.login = login;
    this.password = password;
    this.role = role;
    this.privateEmail = privateEmail;
    this.person = person;
  }
//getters and setters

使用此方法获取控制器中的所有秘密:

  @GetMapping("/allSecrets")
  public ResponseEntity<List<SecretDataOutput>> getAllSecretData() {
    Iterable<SecretData> allSecretData = service.findAllSecretData();
    List<SecretDataOutput> secretDataOutputList = new ArrayList<>();

    allSecretData.forEach(secretData -> {
      long id = secretData.getId();
      String login = secretData.getLogin();
      String password = secretData.getPassword();
      String privateEmail = secretData.getPrivateEmail();
      String role = secretData.getRole();
      Person person = secretData.getPerson();
      SecretDataOutput secretDataOutput = new SecretDataOutput(id, login, password, role, privateEmail, person);
      secretDataOutputList.add(secretDataOutput);
    });

    return new ResponseEntity<>(secretDataOutputList, HttpStatus.OK);
  }

另外,我希望在将 a 保存Person到 a时SecretData,您正在执行双向映射:

  @GetMapping("/addSecret")
  public String storeSecretData() {
    Person p = new Person("pname", "pLastName", new Date(), "male", "pOrientation", "unmarried", "pProvince", "pCity", "pSelfDesc",
        "pLifeMotto", "pThought", "pPhoto", "pProfession", "pEducation", "pEmail");
    SecretData data = new SecretData("secretLogin", "secretPassword", "secretRole", "secretPrivateEmail");//use this constructor and not the one with the extra Person parameter
    data.addPerson(p); //new method to be added in SecretData class
    try {
      service.saveSecret(data);
      return "Saved";
    } catch (Exception e) {
      return "Failed";
    }
  }

将此方法添加到您的SecretData课程中:

  public void addPerson(Person person) {
    this.person = person;
    person.setSecretData(this);
  }

在此处输入图像描述将是 Postman 中的输出


推荐阅读