μ€λλ μ€μ κ³Ό μ€νμκ° λμ ν νλ‘μ νΈλ₯Ό μ§ννμκ³ , μ€κ°μ 1μκ° μ λ μ€κ° λ°ν μ κ²μ΄ μμλ€.
JPA μ°κ΄ κ΄κ³μ λν μλ¬μ λν΄ μ 리 νκ² μ΅λλ€.transientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing
μ΄λ¬ν μλ¬κ° λ°μν μ΄μ λ μ°κ΄ κ΄κ³μ μ£ΌμΈμ λ°μ΄ν°λ₯Ό λ£μ§μκ³ μμ ν
μ΄λΈμ λ°μ΄ν°λ₯Ό λ£μΌλ €κ³ νλ©΄ μλ¬κ° λ°μνκ² λ©λλ€.
(μ°κ΄κ΄κ³ λ©μλκ° μλ κ²½μ°)
@JoinColumn ν€μλλ λ€λ₯Έ 컬λΌκ³Ό μ‘°μΈ νλ€λ λ» μ΄λ©°, FK μ¦ μΈλν€λ₯Ό κ°μ§λ μͺ½μ΄ μ°κ΄κ΄κ³ μ£ΌμΈμ΄ λκ² λ©λλ€.
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "product_id")
private Product product;
mappedBy ν€μλλ μμ ν
μ΄λΈκ³Ό κ°μ μλ―Έλ‘ μκ° νλ©΄ λ κ² κ°μ΅λλ€.
@OneToMany(
mappedBy = "product",
orphanRemoval = true)
@Builder.Default
private List<Image> productImages = new ArrayList<>();
μ΄λ¬ν Entity ν΄λμ€ κ΄κ³μμ
public void create(CreateRequest createRequest, MultipartFile images)
throws IOException {
if (isImageExists(images)) {
// Productλ₯Ό λ¨Όμ μ μ₯ νμ§ μμΌλ©΄ μμ μλ¬κ° λ°μνλ€.
// μ΄μ λ‘λ Productλ₯Ό μ μ₯νμ§ μμΌλ©΄, JoinColumnμ product_idλ₯Ό μμκ° μλ€.
Product product = initProduct(createRequest);
imageService.uploadImage(product, images);
}
}
ν΄κ²° λ°©λ²μΌλ‘λ @ManyToOne, @OneToOne, @OneToManyμ μ°κ΄κ΄κ³ μ΄λ
Έν
μ΄μ
μ cascade ν€μλλ₯Ό μμ±νμ¬ μμμ±μ μ μ΄ ν μ μλ€κ³ ν©λλ€.
β‘ μμ§ μ λͺ¨λ₯΄λ μνμμ μ 리νλ κ² λ³΄λ€ νλ‘μ νΈκ° μΌμΆ λλκ°λ©΄ μ μ© ν΄λ³΄λ©΄μ μ 리 ν΄λμΌκ² λ€.
(μ€μ λ‘ νμ¬μμλ ν μ΄λΈμ DROP ν μΌμ΄ κ±°~μ μλ€κ³ νλ€)
[23000][1451] (conn=3) Cannot delete or update a parent row: a foreign key constraint fails.
μ΄λ¬ν μλ¬λ₯Ό λ§μ£Ό νκ² λμλλ°, μ΄μ λ‘λ νμ¬ μμ νλ €λ ν μ΄λΈμ λλ νμ΄ λ€λ₯Έ ν μ΄λΈμμ μ°Έμ‘° νκ³ μκΈ° λλ¬Έμ λλ€.
β‘ ν΄κ²° λ°©λ² μΌλ‘λ μ°Έμ‘°νκ³ μλ ν μ΄λΈμ μ°Έμ‘°λ₯Ό ν΄μ (μμ ) νλ κ² μ λλ€. (μ°Έμ‘°νλ ν μ΄λΈμ λ¨Όμ DROP)
REFERENCE : https://bcp0109.tistory.com/344
Response (μλ΅) DTO ν΄λμ€λ₯Ό 곡ν΅μΌλ‘ μ¬μ©νλ©΄ μ’μκ² κ°λ€λ μ견μ μ μνμ
¨λ€. (μ λ€λ¦ μ¬μ©)@Getter
@Setter
public class PageResponse<T> {
private List<T> content;
private int pageNumber;
private int pageSize;
private int totalPages;
private long totalElements;
public PageResponse(Page<T> page) {
this.content = page.getContent();
this.pageNumber = page.getNumber() + 1;
this.pageSize = page.getSize();
this.totalPages = page.getTotalPages();
this.totalElements = page.getTotalElements();
}
}
μλμ μ½λλ νμ΄μ§ μ‘°νλ₯Ό μν 컨νΈλ‘€λ¬ λ¨μ
λλ€.
defaultValue 쑰건μ μμ±ν¨μΌλ‘μ¨ 0λΆν° μμνλ νμ΄μ§ λλ²κ° 1λΆν° μμν μ μκ² λ©λλ€.
@GetMapping("/all")
public RsData readPageByProduct(@RequestParam(name = "pageNumber",
defaultValue = PAGE_START_NUMBER) Integer page) {
Pageable pageRequest = PageRequest.of(page - 1, 5);
Page<ViewAllResponse> pageByProduct =
productService.readPageByProduct(pageRequest);
// νμ
μ μ λ€λ¦μΌλ‘ λ°κΈ° λλ¬Έμ λ€μν κ°μ²΄λ‘ λκ²¨μ€ μ μλ€.
return RsData.successOf(new PageResponse<>(pageByProduct));
}
β‘ μ°λ¦¬ νμ μ μΈνκ³ λ€λ₯Έ νλ€μ PDF νΉμ PPT μ λλ§μΌλ‘ λ°νλ₯Ό μ§ν νμλλ°, μ°λ¦¬νμ λ
Έμ
μ μ 리ν API μλ ν¬μΈνΈ, ERDλ± κ³Ό μΉ νμ΄μ§λ₯Ό μ΄λμ λ ꡬν ν΄μ μΉ νμ΄μ§ μΊ‘μ³λ‘ Flow λ₯Ό μ€λͺ
νμλ€.
ngrinder Tool (λꡬ)λ₯Ό μ¬μ©νμ¬ μ±λ₯ ν
μ€νΈ (λΆν ν
μ€νΈ) λ₯Ό μ§ννκ³ μΆκ³ , μλ§ μ§νν μμ μ
λλ€.
(ν¬μ€νΈ 맨μμλ μ±λ₯ ν
μ€νΈλ₯Ό μ§μνμ§λ§, ngrinder λ λκ·λͺ¨ λΆμ°λ(?) νκ²½μ νΉν λμ΄μλ€κ³ ν©λλ€.)
β‘ ν¬μ€νΈλ§¨μΌλ‘λ API μ±λ₯ ν
μ€νΈλ₯Ό ν΄λ³΄μμ΅λλ€. ngrinder Toolμ μ¬μ©νμ¬ μ±λ₯ (λΆν) ν
μ€νΈλ₯Ό μ§νν λ μ°¨μ΄μ μ λ€λ€ λ³΄κ² μ΅λλ€.