我正在嘗試為學校專案創建一個 Rest API。因此我正在嘗試保存/編輯嵌套物件。我有兩個看起來像這樣的雙向物體:
物體A
@Entity
public class EntityA {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
@Column(name = "id", nullable = false)
@JsonProperty("id")
private int id;
@Column(name = "field1", nullable = false, length = -1)
@JsonProperty("field1")
private String field1;
@Column(name = "field2", nullable = false, length = -1)
@JsonProperty("field2")
private String field2;
@OneToMany(mappedBy = "entityA", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JsonProperty("entityB")
private List<EntityB> entityB;
public EntityA() {
}
//Getter Setter
}
物體B
@Entity
public class EntityB {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
@Column(name = "id", nullable = false)
@JsonProperty("id")
private int id;
@Column(name = "field1", nullable = false)
@JsonProperty("field1")
private Date field1;
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(...)
@JsonProperty("entityA")
private EntityA entityA;
public EntityB() {
}
//Getter Setter
}
作為 RequestBody,我將得到如下所示的 JSON。
{
"field1": "Test",
"field2": "User",
"entityB": [
{
"field1": "30.03.2022"
}
]
}
現在 Spring 會自動映射欄位,但是一旦我嘗試將其保存到我的資料庫中,我會收到一個錯誤,因為EntityBfor中的關系EntityA是空的。我已經看到了一個解決方案,我應該遍歷EntityB串列并添加EntityA. 我用for-each嘗試過,但它仍然說它為空。
我究竟做錯了什么?
public EntityA createEntityA(EntityA entityA) {
for(EntityB entityB : entityA.getEntityB()){
entityB.setEntityA(entityA);
}
return entityARepository.save(entityA);
}
編輯:
控制器
@PostMapping(value = {"/json/entitya/"})
@ResponseBody
public EntityA createEntityAJson(@RequestBody EntityA entityA) {
return entityAService.createEntityA(entityA);
}
服務
@Service
public class EntityAService {
@Autowired
private EntityARepository entityARepository;
public EntityA createEntityA(EntityA entityA) {
return entityARepository.save(entityA); //in this line the error appears
}
}
錯誤資訊
null value in column "entityA" violates not-null constraint
uj5u.com熱心網友回復:
@Service
public class EntityAService {
@Autowired
private EntityARepository entityARepository;
@Autowired
private EntityBRepository entityBRepository;
public EntityA createEntityA(EntityA entityA) {
// create an empty arrayList to stock the entities B retrieveed from the DB
List<EnityB> lst = new ArrayList<>();
// get the entities B from the JSON and sabe it to the DB
for(EntityB entityB : entityA.getEntityB()){
entityB.setEntityA(entityA);
entityBRepository.save(entityB); // you should save entities B to the DataBase before
Optional<EntityB > opt = entityBRepository.findById(entityB.getId());
EntityB b = opt.get();
// add the entities B retrieved from the DB to the arrayList
lst.add(b);
}
// set the EntityB list with the new List from the DB ( include ids ..)
entityA.setEntityB(lst);
// save the entityA to the DB
return entityARepository.save(entityA);
}
}
uj5u.com熱心網友回復:
我猜這里發生的事情是 JPA 注釋中不可為空的資料型別或其他隱藏欄位的 id 欄位被 JPA 的 json 反序列化設定為錯誤的值,以了解它們是新物體. 在 Java 代碼中手動創建這些物體可能會解決問題。
您不應該重用您的物體類作為 API 的資料傳輸物件。讓類同時包含特定于資料庫的注釋和 JSON 序列化的注釋是一個壞主意,它違反了單一職責原則 (SRP)。
為您的 API 端點創建單獨的 DTO 類,然后從資料庫中讀取物體并將值從 DTO 物件復制到物體,然后再保存。
// Receive DTO
// Read entity from DB if update or create new entities if insert
// Copy values from DTO to entitiy
// Save entity
我認為如果你應用這種模式,你的問題就會消失。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/455642.html
上一篇:在JavaRestAssured框架中,有沒有辦法使用POJO類來使用x-www-form-urlencoded表單引數?
下一篇:OracleRestAPI多行
