Spring 使用JPA更新外键

Spring 使用JPA更新外键,spring,jpa,Spring,Jpa,我创建了两个实体: @Entity @Table(name="products") public class ProductEntity { @Id @GeneratedValue(strategy= GenerationType.IDENTITY) private Long id; @Column(nullable = false) private String productKeyId; // many to one relationsh

我创建了两个实体:

@Entity
@Table(name="products")
public class ProductEntity {

    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String productKeyId;

    // many to one relationship with category
    @ManyToOne
    @JoinColumn(name = "category_id")
    private CategoryEntity category;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private double price;

    @Column(nullable = false)
    private int qty;

    private String imgPath;

    // getters & setters
}
以及:

@Entity
@Table(name="categories")
public class CategoryEntity {

    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private Long id;

    @Column(length = 30, nullable = false)
    private String categoryKeyId;

    @Column(nullable = false)
    private String name;

    @ManyToOne(optional = true, fetch = FetchType.LAZY)
    @JoinColumn(name="parent_id", nullable=true)
    private CategoryEntity parentCategory;

    // allow to delete also subcategories
    @OneToMany(mappedBy="parentCategory", cascade = CascadeType.ALL)
    private List<CategoryEntity> subCategories;

    //Here mappedBy indicates that the owner is in the other side
    @OneToMany(fetch = FetchType.EAGER, mappedBy = "category", cascade = CascadeType.REMOVE)
    private List<ProductEntity> products;
}
在我的服务中,我尝试分别更新这两部分:

@Override
public ProductDto updateProduct(String productKeyId, ProductDto productDto) {
    // create a return object of type Product

    ProductDto returnValue = new ProductDto();

    // create Entity objects to request on the database
    ProductEntity productEntity = productRepository.findByProductKeyId(productKeyId);
    CategoryEntity categoryEntity = categoryRepository.findCategoryEntityByProductKeyId(productKeyId);

    ModelMapper modelMapper = new ModelMapper();

    if (productEntity == null)
        throw new ApplicationServiceException(ErrorMessages.NO_RECORD_FOUND.getErrorMessage());

    productEntity.setProductKeyId(productKeyId);
    productEntity.setName(productDto.getName());
    productEntity.setPrice(productDto.getPrice());
    productEntity.setQty(productDto.getQty());
    productEntity.setImgPath(productDto.getImgPath());

    // update the category
    CategoryEntity updatedCategory = categoryRepository.save(categoryEntity);
    productEntity.setCategory(updatedCategory);

    // productEntity.setCategory(categoryEntity);

    System.out.println("product entity : " + productEntity.toString());

    ProductEntity updatedProduct = productRepository.save(productEntity);

    updatedProduct.setCategory(updatedCategory);

    returnValue = modelMapper.map(updatedProduct, ProductDto.class);

    return returnValue;
}

不幸的是,它似乎没有像预期的那样起作用。产品更新后,类别保持不变

多亏了Janar和Repoker,我终于解决了我的问题

@Override
public ProductDto updateProduct(String productKeyId, ProductDto productDto) {
    // create a return object of type Product
    ProductDto returnValue = new ProductDto();

    // create Entity objects to request on the database
    ProductEntity productEntity = productRepository.findByProductKeyId(productKeyId);
    CategoryEntity categoryEntity = categoryRepository.findByCategoryKeyId(productDto.getCategory().getCategoryKeyId());
    //CategoryEntity categoryEntity = categoryRepository.findCategoryEntityByProductKeyId(productKeyId);

    ModelMapper modelMapper = new ModelMapper();

    if (productEntity == null)
        throw new ApplicationServiceException(ErrorMessages.NO_RECORD_FOUND.getErrorMessage());

    productEntity.setProductKeyId(productKeyId);
    productEntity.setName(productDto.getName());
    productEntity.setPrice(productDto.getPrice());
    productEntity.setQty(productDto.getQty());
    productEntity.setImgPath(productDto.getImgPath());

    // update the category
    CategoryEntity updatedCategory = categoryRepository.save(categoryEntity);
    productEntity.setCategory(productEntity.getCategory());

    // productEntity.setCategory(categoryEntity);

    System.out.println("product entity : " + productEntity.toString());

    ProductEntity updatedProduct = productRepository.save(productEntity);

    updatedProduct.setCategory(updatedCategory);

    returnValue = modelMapper.map(updatedProduct, ProductDto.class);

    return returnValue;
}

我没有保留输入的新值,而是保留最初设置的值…

您似乎没有更改类别的任何字段?您查询类别,然后保存查询的结果,而不做任何操作。正如@Janar所说,updatedCategory没有任何更改,而且您似乎也没有保存/更新updatedCategory实体
@Override
public ProductDto updateProduct(String productKeyId, ProductDto productDto) {
    // create a return object of type Product
    ProductDto returnValue = new ProductDto();

    // create Entity objects to request on the database
    ProductEntity productEntity = productRepository.findByProductKeyId(productKeyId);
    CategoryEntity categoryEntity = categoryRepository.findByCategoryKeyId(productDto.getCategory().getCategoryKeyId());
    //CategoryEntity categoryEntity = categoryRepository.findCategoryEntityByProductKeyId(productKeyId);

    ModelMapper modelMapper = new ModelMapper();

    if (productEntity == null)
        throw new ApplicationServiceException(ErrorMessages.NO_RECORD_FOUND.getErrorMessage());

    productEntity.setProductKeyId(productKeyId);
    productEntity.setName(productDto.getName());
    productEntity.setPrice(productDto.getPrice());
    productEntity.setQty(productDto.getQty());
    productEntity.setImgPath(productDto.getImgPath());

    // update the category
    CategoryEntity updatedCategory = categoryRepository.save(categoryEntity);
    productEntity.setCategory(productEntity.getCategory());

    // productEntity.setCategory(categoryEntity);

    System.out.println("product entity : " + productEntity.toString());

    ProductEntity updatedProduct = productRepository.save(productEntity);

    updatedProduct.setCategory(updatedCategory);

    returnValue = modelMapper.map(updatedProduct, ProductDto.class);

    return returnValue;
}