正在从父实体的集合中删除子实体 class

Deleting child entity from set in parent class

我正在尝试将图像文件附加到名为产品的实体。我可以很好地创建产品和图像,但是当我尝试删除图像时出现以下错误。

HTTP 500 - 请求处理失败;嵌套异常是 org.hibernate.PersistentObjectException:传递给持久化的分离实体:com.IJM.model.Product

产品Class

@Entity
@Table(name = "Product")
public class Product {

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

@NotNull
@Size(min = 3, max = 10)
@Column(name = "Code", nullable = false)
private String code;

@NotNull
@Size(min = 3, max = 50)
@Column(name = "Name", nullable = false)
private String name;

@Size( max = 50)
@Column(name = "Description", nullable = false)
private String description;

@ManyToOne(cascade = CascadeType.MERGE)
@JoinColumn(name = "Id_Category")
private Category category;

@ManyToOne(cascade = CascadeType.MERGE)
@JoinColumn(name = "Id_Unit")
private Unit unit;

@OneToMany(cascade = CascadeType.ALL,
        fetch= FetchType.EAGER,
        orphanRemoval = true,
        mappedBy="product")
private Set<Image> images;

public String getCode() {
    return code;
}

public void setCode(String code) {
    this.code = code;
}

public String getDescription() {
    return description;
}

public void setDescription(String description) {
    this.description = description;
}
public Long getId() {
    return id;
}
public void setId(Long id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public Category getCategory() {
    return category;
}

public void setCategory(Category category) {
    if(this.category==null||!this.category.equals(category))
    {
        this.category=category;
    }
    return;
}

public Unit getUnit() {
    return unit;
}

public void setUnit(Unit unit) {
    if(this.unit==null||!this.unit.equals(unit))
    {
        this.unit=unit;
    }
    return;
}

public Set<Image> getImages() {
    return images;
}

public void setImages(Set<Image> images) {
    this.images = images;
}
}

图片Class

@Entity
@Table(name = "product_Image")
public class Image {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id", nullable = false)
private long id;

@Lob
@Column(name = "File", nullable = false)
private byte[] file;

@Column(name = "Checksum",nullable = false)
private String checksum;

@Column(name = "Extension",nullable = false)
private String extension;

@Column(name = "File_Name",nullable = false)
private String file_name;

@Column(name = "Size",nullable = false)
private int size;

@Column(name = "Last_Updated",nullable = false)
private Timestamp last_Updated;


@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name="Id_Product")
private Product product;

@ManyToOne(cascade = CascadeType.MERGE)
@JoinColumn(name="Id_Directory")
private Directory directory;

public long getId() {
    return id;
}

public void setId(long id) {
    this.id = id;
}

public byte[] getFile() {
    return file;
}

public void setFile(byte[] file) {
    this.file = file;
}

public String getChecksum() {
    return checksum;
}

public void setChecksum(String checksum) {
    this.checksum = checksum;
}

public String getExtension() {
    return extension;
}

public void setExtension(String extension) {
    this.extension = extension;
}

public String getFile_name() {
    return file_name;
}

public void setFile_name(String file_name) {
    this.file_name = file_name;
}

public int getSize() {
    return size;
}

public void setSize(int size) {
    this.size = size;
}

public Timestamp getLast_Updated() {
    return last_Updated;
}

public void setLast_Updated(Timestamp last_Updated) {
    this.last_Updated = last_Updated;
}

public Product getProduct() {
    return product;
}

public void setProduct(Product product) {
    this.product = product;
}

public Directory getDirectory() {
    return directory;
}

public void setDirectory(Directory directory) {
    this.directory = directory;
}   

这是控制器调用删除方法的代码

@RestController
@RequestMapping("/image")
public class ImageController {

@Autowired
ProductService productService;

@Autowired
ImageService imageService;

private static final String productImagePath="C:\IJM\Images\Product\";

@RequestMapping(value = "/product/{code}", method = RequestMethod.DELETE)
public ResponseEntity<Image> deleteProductImage(@PathVariable("code") String code) {
    System.out.println("Fetching & Deleting Image for product " + code);
    code = code.toUpperCase();

    if (!productService.isProductExist(code)) {
        System.out.println("Product with code " + code + " not found");
        return new ResponseEntity<Image>(HttpStatus.NOT_FOUND);
    }
    else
    {
        Product product = productService.findProductByCode(code);
        if(product.getImages()!=null)
        {
            for(Image image:product.getImages())
            {
                product.getImages().remove(image);
                image.setProduct(null);
                imageService.deleteImage(image.getId());
            }
            productService.saveProduct(product);
            try{

                File file = new File(productImagePath+code);

                if(FileDeleter.removeDirectory(file)){
                    System.out.println(file.getName() + " is deleted!");
                }else{
                    System.out.println("Delete operation is failed.");
                }

            }catch(Exception e){

                e.printStackTrace();

            }
        }
    }

    return new ResponseEntity<Image>(HttpStatus.NO_CONTENT);
}
}

万一其他人想知道..服务只是调用 DAO

    @Override
public void deleteImage(long id) {
    Image image = imageDao.findById(id);
    imageDao.delete(image);

}

这就是道Class

@Repository("imageDao")
public class ImageDaoImpl extends AbstractDao<Long,Image> implements ImageDao{


@Override
public void delete(Image image) {
    super.delete(image);

}
}

这是我的抽象 DAO 中的代码 class

public void delete(T entity) {
    getSession().delete(entity);
}

似乎这些行的顺序不正确。

product.getImages().remove(image);
image.setProduct(null);
imageService.deleteImage(image.getId());

也不确定imageService.deleteImage(image.getId());在做什么。不需要。

请按以下方式尝试。

for(Image image:product.getImages())
   {
    image.setProduct(null);
    product.getImages().remove(image);
   }
productService.saveProduct(product);

这应该足够了。我知道更改顺序没有任何意义,但它对我有用。