私はまだ JPA の概念を把握しており、私の質問に対する答えがどこにも見つからないようです!
推定
どちらのクラスにも @GeneratedValue(strategy = GenerationType.IDENTITY) の注釈が付けられています。すべてのゲッターとセッターがあります。
Parent{
....
@OneToMany(mappedBy = "parent")
Collection<Child> children;
....
}
Child{
...
@JoinColumn(name = "parent", referencedColumnName = "id", nullable = true)
@ManyToOne(optional = false)
Parent parent;
...
}
次に、標準の JpaRepository を実装し、コントローラーをセットアップしました
ここに問題があり
ます すべての子レコードを照会すると、特定の親にマップされた最初の子レコードだけが親エンティティ オブジェクトを持ちます。残りは、親エンティティを参照する ID を持ちます。
次に例を示します: POSTMAN からすべての子を取得すると、次のように返されます。
[
{
"id": 1,
"name": "child1",
"parent": {
"id": 1,
"firstName": "..."
...
}
},
{
"id": 2,
"name": "child2",
"parent": 1
}
{
"id": 3,
"name": "child3",
"parent": {
"id": 2,
"firstName": "..."
...
}
},
{
"id": 4,
"name": "child4",
"parent": 2
}
]
ご覧のとおり、最初にその親にマップされているchild2
だけです! 同様に、最初にその親にマップされただけです!"parent": 1
child1
child4
"parent": 2
child3
誰でもこの動作を説明できますか? 親を試しfetch = FetchType.EAGER
てみましたが、役に立ちませんでした!私は、すべての子が包括的な親オブジェクトを持ち、別の DB トリップを防ぐことを期待しています。
前もって感謝します!
実際のクラスで質問を更新する:
親
package backend.application.payroll.models;
import com.fasterxml.jackson.annotation.*;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.*;
@Data
@Entity
@Table(name = "employees")
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")
public class Employee implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "emp_code", nullable = false)
private String empCode;
@Column(name = "first_name", nullable = false)
private String firstName;
@Column(name = "middle_name", nullable = true)
private String middleName;
@Column(name = "last_name", nullable = false)
private String lastName;
@Column(name = "dob", nullable = false)
@Temporal(TemporalType.DATE)
private Date dob;
@Column(name = "id_number", nullable = true)
private String idNumber;
@Column(name = "passport_number", nullable = true)
private String passportNumber;
@Column(name = "email_address", nullable = true)
private String emailAddress;
@OneToOne(cascade = CascadeType.DETACH)
@JoinColumn(name = "pay_grade", referencedColumnName = "id", nullable = true)
private Salary payGrade;
@Column(name = "basic_pay", nullable = true)
private BigDecimal basicPay;
@OneToOne(cascade = CascadeType.DETACH)
@JoinColumn(name = "department", referencedColumnName = "id", nullable = true)
private Department department;
@OneToOne(cascade = CascadeType.DETACH)
@JoinColumn(name = "position", referencedColumnName = "id", nullable = true)
private Position position;
@Column(name = "tax_number", nullable = true)
private String taxNumber;
@Column(name = "hire_date", nullable = true)
@Temporal(TemporalType.DATE)
private Date hireDate;
@Column(name = "address1", nullable = true)
private String address1;
@Column(name = "address2", nullable = true)
private String address2;
@Column(name = "postal_code", nullable = true)
private String postalCode;
//country
@Column(name = "phone_number", nullable = true)
private String phoneNumber;
//banking details
//HERE IT WORKS FINE SINCE IT'S ONETOONE - YOU CAN IGNORE
@OneToOne(mappedBy = "employee")
//@JsonManagedReference//used in conjunction with @JsonBackReference on the other end - works like @JsonIdentityInfo class annotation.
private User user;
//THIS IS WHAT CAUSING THE PROBLEM
@OneToMany(mappedBy = "owner", fetch = FetchType.LAZY)
//@JsonBackReference
@JsonIgnore
private Set<Costcentre> costcentres = new HashSet<>();
public Employee() {
}
}
子
package backend.application.payroll.models;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import lombok.Data;
import javax.persistence.*;
import java.io.Serializable;
@Entity
@Table(name = "costcentres")
@Data
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class Costcentre implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "name", nullable = false)
private String name;
@Column(name = "description", nullable = true)
private String description;
@ManyToOne(cascade = CascadeType.DETACH, fetch = FetchType.EAGER)
@JoinColumn(name = "owner", referencedColumnName = "id", nullable = true)
//@JsonManagedReference
private Employee owner; //CULPRIT
public Costcentre() {
}
public Costcentre(long id, String name, String description) {
super();
this.id = id;
this.name = name;
this.description = description;
}
}