【问题标题】:Deleting child entity from set in parent class从父类中的集合中删除子实体
【发布时间】:2016-05-30 18:26:14
【问题描述】:

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

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

产品类别

@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;
}
}

图像类

@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);

}

这是道家

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


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

}
}

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

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

【问题讨论】:

    标签: java hibernate mapping many-to-one cascading-deletes


    【解决方案1】:

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

    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);
    

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

    【讨论】:

    • :c 看来它对我的代码没有任何影响。我发布了更多内容以防我出错。
    • 您是否尝试删除 deleteImage 调用。您得到的错误是由于您已经删除的图像实体,如果是休眠,saveProduct 实现应该是 saveOrUpdate(product) 或在 JPA 的情况下是 merge(product)。
    • 大声笑..是的,它需要更新..就是这样,对不起,我认为这很愚蠢!非常感谢您的时间和知识!
    猜你喜欢
    • 2013-03-09
    • 1970-01-01
    • 1970-01-01
    • 2010-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    相关资源
    最近更新 更多