[英]Spring Data JPA - How to persist nested object any existing or not
[英]Spring Data JPA - Persisting new Object with existing nested child
我確實有兩個名為 School 和 Level 的實體,它們具有多對多關系。
@Data
@Entity
public class School {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "school_generator")
@SequenceGenerator(name="school_generator", sequenceName = "school_seq", allocationSize=1)
@Column(name = "school_id")
private Long id;
@NotBlank
private String name;
@NotBlank
private String city;
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinTable(
name = "school_level",
joinColumns = @JoinColumn(name = "school_id"),
inverseJoinColumns = @JoinColumn(name = "level_id"))
private Set<Level> levels = new HashSet<>();
}
@Data
@Entity
public class Level implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "level_generator")
@SequenceGenerator(name = "level_generator", sequenceName = "level_seq", allocationSize = 1)
@Column(name = "level_id")
private Long id;
@NotBlank
@Column(nullable = false, unique = true)
private String name;
}
我的SchoolController
,Rest 控制器,有一個采用 SchoolDTO 的 create 方法(現在它與實體具有相同的結構)。
當我發布 DTO 時,嵌套的子列表 Levels 僅填充了現有的 Levels id(因為之前創建了 Levels)。
當我嘗試通過 JPARepository 保存方法保存時...拋出此消息的異常:
"detached entity passed to persist: com.salimrahmani.adawat.domain.Level; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: com.salimrahmani.adawat.domain.Level",
"trace": "org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist:
問題是通過迭代每個 Level Id 來解決的……使用 JPA Repository 方法getOne
(調用entityManager.getReference
)獲取引用,然后加載正確的模型,然后成功持久化。
@PostMapping("/{id}/grades")
public ResponseEntity<SchoolDTO> addLevelToPackage(@PathVariable Long id, @RequestBody @Valid LevelDTO levelDTO) {
return schoolService.findById(id)
.map(school -> {
Level level = levelMapper.map(levelDTO);
if(level.getId() != null) {
level = levelService.getOne(level.getId());
school.getLevels().add(level);
} // else error
School saved = schoolService.save(school);
return ResponseEntity.ok(schoolMapper.map(saved));
}).orElseGet(() -> ResponseEntity.notFound().build());
}
我的問題是:這是在 Spring Data 中發布關聯的“唯一”正確方法嗎? 或者,有沒有更好的辦法?
在addLevelToPackage
函數中為什么使用map
schoolService.findById(id).map..
如果我認為 schoolService 將僅返回具有給定 id 的實體 School 的一個實例。 我認為用以下內容替換地圖就足夠了:
...
School theSchool = schoolService.findById(id);
Level theLevel = levelService.getOne(levelDTO.getId());
theSchool.getLevels().add(theLevel);
School saved = schoolService.save(theSchool);
return ResponseEntity.ok(schoolMapper.map(saved));
...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.