spring - 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 它也不起作用。
解决方案
您应该创建一个新类,该类应该代表您在响应中需要的输出格式。
表示输出格式的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);
}
推荐阅读
- .net-core - 为什么 dotnet core 3.1 中的 new Uri("/") 在 *nix 和 windows 中表现不同?
- can-bus - 为什么我在 CANoe 的 CAN 跟踪上看到红叉标记的消息?
- azure-data-factory - 分配给 ADF 管道的默认资源是什么
- http - 什么是浏览器术语中的顶级导航以及可以通过哪些方式触发它?
- authentication - 疑难解答“不允许同一用户使用多个用户名与服务器或共享资源建立多个连接。”
- python - 如何返回多列并限制行
- vb.net - 如何让这个基本的 OOP 代码在 Visual Basic 中工作?
- javascript - 如何在样本上的 Magento 2 中初始化手风琴,在产品页面上
- go - go Println 数组失败,复合文字类型字符串无效
- c# - 带有重复图片框的碰撞检测